def proxy(self): """Return a Deferred that will result in a proxy object in the future.""" d = Deferred(self.loop) self._proxy_deferreds.append(d) if self._proxy: d.callback(self._proxy) return d
def proxy(self): """Return a Deferred that will result in a proxy object in the future.""" d = Deferred(self.loop) self._proxy_deferreds.append(d) if self._proxy: d.callback(self._proxy) return d
def begin_call(self, method, *args): """Perform an asynchronous remote call where the return value is not known yet. This returns immediately with a Deferred object. The Deferred object may then be used to attach a callback, force waiting for the call, or check for exceptions. """ d = Deferred(self.loop, logger=logger) d.request = self.request_num self.requests[self.request_num] = d self.protocol.send_request(d.request, method, args) self.request_num += 1 return d
def __init__(self, loop, sock, addr, timeout): self.loop = loop self.sock = sock self.addr = addr self.timeout = timeout self.connect_watcher = pyev.Io(self.sock, pyev.EV_WRITE, self.loop, self._connected) self.timeout_watcher = pyev.Timer(self.timeout, 0.0, self.loop, self._timeout) self.deferred = Deferred(self.loop) self.started = False self.connected = False self.timedout = False self.errored = False
def _connect(self, sock, addr, timeout): """Start watching the socket for it to be writtable.""" if self.connection: raise SocketClientConnectedError() if self.connector: raise SocketClientConnectingError() self.connect_deferred = Deferred(self.loop) self.sock = sock self.addr = addr self.connector = Connector(self.loop, sock, addr, timeout) self.connector.deferred.add_callback(self._connected) self.connector.deferred.add_errback(self._connect_failed) self.connector.start() return self.connect_deferred
def __init__(self, loop, sock, addr, timeout): self.loop = loop self.sock = sock self.addr = addr self.timeout = timeout self.connect_watcher = pyev.Io(self.sock, pyev.EV_WRITE, self.loop, self._connected) self.timeout_watcher = pyev.Timer(self.timeout, 0.0, self.loop, self._timeout) self.deferred = Deferred(self.loop) self.started = False self.connected = False self.timedout = False self.errored = False
class Connector(object): """State machine for a connection to a remote socket.""" def __init__(self, loop, sock, addr, timeout): self.loop = loop self.sock = sock self.addr = addr self.timeout = timeout self.connect_watcher = pyev.Io(self.sock, pyev.EV_WRITE, self.loop, self._connected) self.timeout_watcher = pyev.Timer(self.timeout, 0.0, self.loop, self._timeout) self.deferred = Deferred(self.loop) self.started = False self.connected = False self.timedout = False self.errored = False def start(self): """Start the connector state machine.""" if self.started: raise ConnectorStartedError() self.started = True try: self.connect_watcher.start() self.timeout_watcher.start() self.sock.connect(self.addr) except IOError as e: self.errored = True self._finish() self.deferred.errback(e) return self.deferred def cancel(self): """Cancel a connector from completing.""" if self.started and not self.connected and not self.timedout: self.connect_watcher.stop() self.timeout_watcher.stop() def _connected(self, watcher, events): """Connector is successful, return the socket.""" self.connected = True self._finish() self.deferred.callback(self.sock) def _timeout(self, watcher, events): """Connector timed out, raise a timeout error.""" self.timedout = True self._finish() self.deferred.errback(TimeoutError()) def _finish(self): """Finalize the connector.""" self.connect_watcher.stop() self.timeout_watcher.stop()
class Connector(object): """State machine for a connection to a remote socket.""" def __init__(self, loop, sock, addr, timeout): self.loop = loop self.sock = sock self.addr = addr self.timeout = timeout self.connect_watcher = pyev.Io(self.sock, pyev.EV_WRITE, self.loop, self._connected) self.timeout_watcher = pyev.Timer(self.timeout, 0.0, self.loop, self._timeout) self.deferred = Deferred(self.loop) self.started = False self.connected = False self.timedout = False self.errored = False def start(self): """Start the connector state machine.""" if self.started: raise ConnectorStartedError() self.started = True try: self.connect_watcher.start() self.timeout_watcher.start() self.sock.connect(self.addr) except IOError as e: self.errored = True self._finish() self.deferred.errback(e) return self.deferred def cancel(self): """Cancel a connector from completing.""" if self.started and not self.connected and not self.timedout: self.connect_watcher.stop() self.timeout_watcher.stop() def _connected(self, watcher, events): """Connector is successful, return the socket.""" self.connected = True self._finish() self.deferred.callback(self.sock) def _timeout(self, watcher, events): """Connector timed out, raise a timeout error.""" self.timedout = True self._finish() self.deferred.errback(TimeoutError()) def _finish(self): """Finalize the connector.""" self.connect_watcher.stop() self.timeout_watcher.stop()
def _connect(self, sock, addr, timeout): """Start watching the socket for it to be writtable.""" if self.connection: raise SocketClientConnectedError() if self.connector: raise SocketClientConnectingError() self.connect_deferred = Deferred(self.loop) self.sock = sock self.addr = addr self.connector = Connector(self.loop, sock, addr, timeout) self.connector.deferred.add_callback(self._connected) self.connector.deferred.add_errback(self._connect_failed) self.connector.start() return self.connect_deferred
class SocketClient(object): """A simple socket client.""" def __init__(self, loop, factory): self.loop = loop self.factory = factory self.connector = None self.connection = None self.connect_deferred = None self.sigint_watcher = pyev.Signal(signal.SIGINT, self.loop, self._interrupt) self.sigint_watcher.start() self.connector = None self.sock = None self.addr = None def _interrupt(self, watcher, events): if self.connection: self.connection.close() def _connect(self, sock, addr, timeout): """Start watching the socket for it to be writtable.""" if self.connection: raise SocketClientConnectedError() if self.connector: raise SocketClientConnectingError() self.connect_deferred = Deferred(self.loop) self.sock = sock self.addr = addr self.connector = Connector(self.loop, sock, addr, timeout) self.connector.deferred.add_callback(self._connected) self.connector.deferred.add_errback(self._connect_failed) self.connector.start() return self.connect_deferred def _connected(self, sock): """When the socket is writtable, the socket is ready to be used.""" logger.debug("socket connected, building protocol") self.protocol = self.factory.build(self.loop) self.connection = Connection(self.loop, self.sock, self.addr, self.protocol, self) self.connector = None self.connect_deferred.callback(self.protocol) def _connect_failed(self, reason): """Connect failed.""" self.connector = None self.connect_deferred.errback(reason) def _disconnect(self): """Disconnect from a socket.""" if self.connection: self.connection.close() self.connection = None def connect(self, timeout=5): """Should be overridden to create a socket and connect it. Once the socket is connected it should be passed to _connect. """ def remove_connection(self, connection): self.connection = None
class TestDeferred(unittest.TestCase): def setUp(self): self.deferred = Deferred(loop) self.result = None def tearDown(self): self.deferred = None self.result = None def set_result(self, result): self.result = result def set_exception(self, exception): self.exception = exception def call_later(self, delay, func, *args, **kwargs): timer = pyev.Timer(delay, 0.0, loop, self._do_later, (func, args, kwargs)) timer.start() return timer def _do_later(self, watcher, events): (func, args, kwargs) = watcher.data func(*args, **kwargs) watcher.stop() def test_callback(self): self.deferred.add_callback(self.set_result) self.deferred.callback(5) self.assertTrue(self.result == 5) def test_callback_chain(self): d = self.deferred d.add_callback(add, 1) d.add_callback(self.set_result) self.deferred.callback(5) self.assertTrue(self.result == 6) def test_log_error(self): """Unhandled exceptions should be logged if the deferred is deleted.""" self.deferred.add_callback(throw_always) self.deferred.callback(None) self.deferred = None # delete it def test_errback(self): self.deferred.add_errback(self.set_result) self.deferred.errback(Exception()) self.assertTrue(isinstance(self.result, Exception)) def test_callback_skips(self): """When a callback raises an exception all callbacks without errbacks are skipped until the next errback is found. """ self.deferred.add_callback(throw_always) self.deferred.add_callback(one_always) self.deferred.add_callback(add, 2) self.deferred.add_errback(one_always) self.deferred.add_callback(self.set_result) self.deferred.callback(None) self.assertTrue(self.result == 1) def test_errback_reraised(self): """If an errback raises, then the next errback is called.""" self.deferred.add_errback(throw_always) self.deferred.add_errback(self.set_result) self.deferred.errback(Exception()) self.assertTrue(isinstance(self.result, Exception)) def test_cancelled(self): self.deferred.cancel() self.assertRaises(CancelledError, self.deferred.errback, Exception("testcancelled")) self.assertRaises(CancelledError, self.deferred.callback, None) self.assertRaises(CancelledError, self.deferred.result) def test_already_called(self): self.deferred.callback(None) self.assertRaises(AlreadyCalledError, self.deferred.errback, Exception("testalreadycalled")) self.assertRaises(AlreadyCalledError, self.deferred.callback, None) self.assertRaises(AlreadyCalledError, self.deferred.cancel) def test_cancel_callback(self): self.deferred = Deferred(loop, cancelled_cb=self.set_result) self.deferred.cancel() self.assertTrue(self.result == self.deferred) def test_result_chain(self): self.deferred.callback(5) self.assertTrue(self.deferred.result() == 5) self.deferred.add_callback(add, 2) self.assertTrue(self.deferred.result() == 7) self.deferred.add_callback(throw_always) self.assertRaises(Exception, self.deferred.result) def test_result(self): self.deferred.callback(5) self.assertTrue(self.deferred.result() == 5) def test_result_exceptioned(self): self.deferred.errback(Exception("exceptioned result")) self.assertRaises(Exception, self.deferred.result) def test_delayed_result(self): now = time.time() t1 = self.call_later(0.5, self.deferred.callback, 5) self.assertTrue(self.deferred.result() == 5) self.assertTrue(time.time() - now > 0.4) def test_delayed_result_chained(self): now = time.time() t1 = self.call_later(0.5, self.deferred.callback, 5) self.deferred.add_callback(add, 4) self.assertTrue(self.deferred.result() == 9) self.assertTrue(time.time() - now > 0.4) def test_delayed_result_timeout(self): t1 = self.call_later(0.5, self.deferred.callback, 5) self.assertRaises(TimeoutError, self.deferred.result, 0.1) def test_delayed_result_cancelled(self): t1 = self.call_later(0.5, self.deferred.callback, 5) t2 = self.call_later(0.2, self.deferred.cancel) self.assertRaises(CancelledError, self.deferred.result, 0.3)
def setUp(self): self.deferred = Deferred(loop) self.result = None
class TestDeferred(unittest.TestCase): def setUp(self): self.deferred = Deferred(loop) self.result = None def tearDown(self): self.deferred = None self.result = None def set_result(self, result): self.result = result def set_exception(self, exception): self.exception = exception def call_later(self, delay, func, *args, **kwargs): timer = pyev.Timer(delay, 0.0, loop, self._do_later, (func, args, kwargs)) timer.start() return timer def _do_later(self, watcher, events): (func, args, kwargs) = watcher.data func(*args, **kwargs) watcher.stop() def test_callback(self): self.deferred.add_callback(self.set_result) self.deferred.callback(5) self.assertTrue(self.result == 5) def test_callback_chain(self): d = self.deferred d.add_callback(add, 1) d.add_callback(self.set_result) self.deferred.callback(5) self.assertTrue(self.result == 6) def test_log_error(self): """Unhandled exceptions should be logged if the deferred is deleted.""" self.deferred.add_callback(throw_always) self.deferred.callback(None) self.deferred = None # delete it def test_errback(self): self.deferred.add_errback(self.set_result) self.deferred.errback(Exception()) self.assertTrue(isinstance(self.result, Exception)) def test_callback_skips(self): """When a callback raises an exception all callbacks without errbacks are skipped until the next errback is found. """ self.deferred.add_callback(throw_always) self.deferred.add_callback(one_always) self.deferred.add_callback(add, 2) self.deferred.add_errback(one_always) self.deferred.add_callback(self.set_result) self.deferred.callback(None) self.assertTrue(self.result == 1) def test_errback_reraised(self): """If an errback raises, then the next errback is called.""" self.deferred.add_errback(throw_always) self.deferred.add_errback(self.set_result) self.deferred.errback(Exception()) self.assertTrue(isinstance(self.result, Exception)) def test_cancelled(self): self.deferred.cancel() self.assertRaises(CancelledError, self.deferred.errback, Exception("testcancelled")) self.assertRaises(CancelledError, self.deferred.callback, None) self.assertRaises(CancelledError, self.deferred.result) def test_already_called(self): self.deferred.callback(None) self.assertRaises(AlreadyCalledError, self.deferred.errback, Exception("testalreadycalled")) self.assertRaises(AlreadyCalledError, self.deferred.callback, None) self.assertRaises(AlreadyCalledError, self.deferred.cancel) def test_cancel_callback(self): self.deferred = Deferred(loop, cancelled_cb=self.set_result) self.deferred.cancel() self.assertTrue(self.result == self.deferred) def test_result_chain(self): self.deferred.callback(5) self.assertTrue(self.deferred.result() == 5) self.deferred.add_callback(add, 2) self.assertTrue(self.deferred.result() == 7) self.deferred.add_callback(throw_always) self.assertRaises(Exception, self.deferred.result) def test_result(self): self.deferred.callback(5) self.assertTrue(self.deferred.result() == 5) def test_result_exceptioned(self): self.deferred.errback(Exception("exceptioned result")) self.assertRaises(Exception, self.deferred.result) def test_delayed_result(self): now = time.time() t1 = self.call_later(0.5, self.deferred.callback, 5) self.assertTrue(self.deferred.result() == 5) self.assertTrue(time.time() - now > 0.4) def test_delayed_result_chained(self): now = time.time() t1 = self.call_later(0.5, self.deferred.callback, 5) self.deferred.add_callback(add, 4) self.assertTrue(self.deferred.result() == 9) self.assertTrue(time.time() - now > 0.4) def test_delayed_result_timeout(self): t1 = self.call_later(0.5, self.deferred.callback, 5) self.assertRaises(TimeoutError, self.deferred.result, 0.1) def test_delayed_result_cancelled(self): t1 = self.call_later(0.5, self.deferred.callback, 5) t2 = self.call_later(0.2, self.deferred.cancel) self.assertRaises(CancelledError, self.deferred.result, 0.3)
def test_cancel_callback(self): self.deferred = Deferred(loop, cancelled_cb=self.set_result) self.deferred.cancel() self.assertTrue(self.result == self.deferred)
def setUp(self): self.deferred = Deferred(loop) self.result = None
class SocketClient(object): """A simple socket client.""" def __init__(self, loop, factory): self.loop = loop self.factory = factory self.connector = None self.connection = None self.connect_deferred = None self.sigint_watcher = pyev.Signal(signal.SIGINT, self.loop, self._interrupt) self.sigint_watcher.start() self.connector = None self.sock = None self.addr = None def _interrupt(self, watcher, events): if self.connection: self.connection.close() def _connect(self, sock, addr, timeout): """Start watching the socket for it to be writtable.""" if self.connection: raise SocketClientConnectedError() if self.connector: raise SocketClientConnectingError() self.connect_deferred = Deferred(self.loop) self.sock = sock self.addr = addr self.connector = Connector(self.loop, sock, addr, timeout) self.connector.deferred.add_callback(self._connected) self.connector.deferred.add_errback(self._connect_failed) self.connector.start() return self.connect_deferred def _connected(self, sock): """When the socket is writtable, the socket is ready to be used.""" logger.debug('socket connected, building protocol') self.protocol = self.factory.build(self.loop) self.connection = Connection(self.loop, self.sock, self.addr, self.protocol, self) self.connector = None self.connect_deferred.callback(self.protocol) def _connect_failed(self, reason): """Connect failed.""" self.connector = None self.connect_deferred.errback(reason) def _disconnect(self): """Disconnect from a socket.""" if self.connection: self.connection.close() self.connection = None def connect(self, timeout=5): """Should be overridden to create a socket and connect it. Once the socket is connected it should be passed to _connect. """ def remove_connection(self, connection): self.connection = None
def test_cancel_callback(self): self.deferred = Deferred(loop, cancelled_cb=self.set_result) self.deferred.cancel() self.assertTrue(self.result == self.deferred)