def __init__(self, cxn): """Create a synchronous wrapper around an asynchronous connection. Args: cxn (labrad.protocol.LabradProtocol): The asynchronous protocol instance for which to provide a synchronous interface. """ self.cxn = cxn self.name = cxn.name self.ID = cxn.ID self.host = cxn.host self.port = cxn.port self._connected = threading.Event() self._connected.set() # Setup a coroutine that will clear the connected flag when the # connection is lost. We launch this but do not wait for the result of # the future because we want this to happen asynchronously in the # background. @defer.inlineCallbacks def handle_disconnect(): try: yield cxn.onDisconnect() except Exception: pass self._connected.clear() concurrent.call_future(handle_disconnect)
def test_synchronous_error(self): def func(): raise ValueError() f = concurrent.call_future(func) with pytest.raises(ValueError): f.result(timeout=0.1)
def test_set_result_outside_reactor(self): @defer.inlineCallbacks def func(f): result = yield concurrent.future_to_deferred(f) defer.returnValue(result) f1 = Future() f2 = concurrent.call_future(func, f1) f1.set_result(1) assert f2.result(timeout=0.1) == 1
def test_asynchronous_func(self): @defer.inlineCallbacks def func(): d = defer.Deferred() reactor.callLater(0, d.callback, 'woot') result = yield d defer.returnValue(result) f = concurrent.call_future(func) assert f.result(timeout=0.1) == 'woot'
def test_set_exception_outside_reactor(self): @defer.inlineCallbacks def func(f): result = yield concurrent.future_to_deferred(f) defer.returnValue(result) f1 = Future() f2 = concurrent.call_future(func, f1) f1.set_exception(ValueError()) with pytest.raises(ValueError): f2.result(timeout=0.1)
def test_set_result_inside_reactor(self): @defer.inlineCallbacks def func(f): d = concurrent.future_to_deferred(f) f.set_result(1) result = yield d defer.returnValue(result) f = Future() future = concurrent.call_future(func, f) assert future.result() == 1
def test_asynchronous_error(self): @defer.inlineCallbacks def func(): d = defer.Deferred() reactor.callLater(0, d.callback, 'woot') result = yield d raise ValueError() f = concurrent.call_future(func) with pytest.raises(ValueError): f.result(timeout=0.1)
def test_set_result_inside_reactor(self): @defer.inlineCallbacks def func(f): d = concurrent.future_to_deferred(f) f.set_exception(ValueError()) result = yield d defer.returnValue(result) f = Future() future = concurrent.call_future(func, f) with pytest.raises(ValueError): future.result()
def connect(host=C.MANAGER_HOST, port=None, name=None, timeout=C.TIMEOUT, **kw): """Create a backend connection to labrad. This connects to labrad asynchronously and then wraps the underlying async connection object in a synchronous TwistedConnection interface. """ name = name or 'Python Client ({})'.format(support.getNodeName()) thread.startReactor() future = concurrent.call_future(getConnection, host, port, name, **kw) cxn = future.result(timeout=timeout) return TwistedConnection(cxn)
def test_synchronous_func(self): def func(): return threadable.isInIOThread() f = concurrent.call_future(func) assert f.result(timeout=0.1)
def sendRequest(self, target, records, *args, **kw): return concurrent.call_future(self.cxn.sendRequest, target, records, *args, **kw)
def sendMessage(self, target, records, *args, **kw): return concurrent.call_future(self.cxn.sendMessage, target, records, *args, **kw).result()
def disconnect(self): if self.connected: concurrent.call_future(self.cxn.disconnect).result() # Wait for the connected flag to go False. while self.connected: time.sleep(0.01)
def context(self): """Create a new context for use with this connection""" return concurrent.call_future(self.cxn.context).result()
def spawn(self, timeout=C.TIMEOUT): """Start a new independent backend connection to the same manager.""" cxn = concurrent.call_future(self.cxn.spawn).result(timeout=timeout) return TwistedConnection(cxn)