Merge pull request #1138 from ajbeamon/python-fix-signal-handler
Python now blocks on a future in Python rather than in native code to…
This commit is contained in:
commit
1d12618f7d
|
@ -30,6 +30,7 @@ import datetime
|
||||||
import platform
|
import platform
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import multiprocessing
|
||||||
|
|
||||||
from fdb import six
|
from fdb import six
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ _network_thread_reentrant_lock = threading.RLock()
|
||||||
|
|
||||||
_open_file = open
|
_open_file = open
|
||||||
|
|
||||||
|
_thread_local_storage = threading.local()
|
||||||
|
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
|
|
||||||
|
@ -593,7 +596,27 @@ class Future(_FDBBase):
|
||||||
return bool(self.capi.fdb_future_is_ready(self.fpointer))
|
return bool(self.capi.fdb_future_is_ready(self.fpointer))
|
||||||
|
|
||||||
def block_until_ready(self):
|
def block_until_ready(self):
|
||||||
self.capi.fdb_future_block_until_ready(self.fpointer)
|
# Checking readiness is faster than using the callback, so it saves us time if we are already
|
||||||
|
# ready. It also doesn't add much to the cost of this function
|
||||||
|
if not self.is_ready():
|
||||||
|
# Blocking in the native client from the main thread prevents Python from handling signals.
|
||||||
|
# To avoid that behavior, we implement the blocking in Python using semaphores and on_ready.
|
||||||
|
# Using a Semaphore is faster than an Event, and we create only one per thread to avoid the
|
||||||
|
# cost of creating one every time.
|
||||||
|
semaphore = getattr(_thread_local_storage, 'future_block_semaphore', None)
|
||||||
|
if semaphore is None:
|
||||||
|
semaphore = multiprocessing.Semaphore(0)
|
||||||
|
_thread_local_storage.future_block_semaphore = semaphore
|
||||||
|
|
||||||
|
self.on_ready(lambda self: semaphore.release())
|
||||||
|
|
||||||
|
try:
|
||||||
|
semaphore.acquire()
|
||||||
|
except:
|
||||||
|
# If this semaphore didn't actually get released, then we need to replace our thread-local
|
||||||
|
# copy so that later callers still function correctly
|
||||||
|
_thread_local_storage.future_block_semaphore = multiprocessing.Semaphore(0)
|
||||||
|
raise
|
||||||
|
|
||||||
def on_ready(self, callback):
|
def on_ready(self, callback):
|
||||||
def cb_and_delref(ignore):
|
def cb_and_delref(ignore):
|
||||||
|
|
|
@ -30,6 +30,7 @@ Bindings
|
||||||
* Golang: Deprecated ``fdb.StartNetwork``, ``fdb.Open``, ``fdb.MustOpen``, and ``fdb.CreateCluster`` and added ``fdb.OpenDatabase`` and ``fdb.MustOpenDatabase``. The preferred way to start the network and get a ``Database`` is by using ``FDB.OpenDatabase`` or ``FDB.OpenDefault``. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
|
* Golang: Deprecated ``fdb.StartNetwork``, ``fdb.Open``, ``fdb.MustOpen``, and ``fdb.CreateCluster`` and added ``fdb.OpenDatabase`` and ``fdb.MustOpenDatabase``. The preferred way to start the network and get a ``Database`` is by using ``FDB.OpenDatabase`` or ``FDB.OpenDefault``. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
|
||||||
* Flow: Deprecated ``API::createCluster`` and ``Cluster`` and added ``API::createDatabase``. The preferred way to get a ``Database`` is by using ``API::createDatabase``. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
|
* Flow: Deprecated ``API::createCluster`` and ``Cluster`` and added ``API::createDatabase``. The preferred way to get a ``Database`` is by using ``API::createDatabase``. `(PR #942) <https://github.com/apple/foundationdb/pull/942>`_
|
||||||
* Golang: Added ``fdb.Printable`` to print a human-readable string for a given byte array. Add ``Key.String()``, which converts the ``Key`` to a ``string`` using the ``Printable`` function. `(PR #1010) <https://github.com/apple/foundationdb/pull/1010>`_
|
* Golang: Added ``fdb.Printable`` to print a human-readable string for a given byte array. Add ``Key.String()``, which converts the ``Key`` to a ``string`` using the ``Printable`` function. `(PR #1010) <https://github.com/apple/foundationdb/pull/1010>`_
|
||||||
|
* Python: Python signal handling didn't work when waiting on a future. In particular, pressing Ctrl-C would not successfully interrupt the program. `(PR #1138) <https://github.com/apple/foundationdb/pull/1138>`_
|
||||||
|
|
||||||
Other Changes
|
Other Changes
|
||||||
-------------
|
-------------
|
||||||
|
|
Loading…
Reference in New Issue