def sleep(duration): """Return a `.Future` that resolves after the given number of seconds. When used with ``yield`` in a coroutine, this is a non-blocking analogue to `time.sleep` (which should not be used in coroutines because it is blocking):: yield gen.sleep(0.5) Note that calling this function on its own does nothing; you must wait on the `.Future` it returns (usually by yielding it). """ f = Future() IOLoop.current().call_later(duration, lambda: f.set_result(None)) return f
def sleep(duration): """Return a `.Future` that resolves after the given number of seconds. When used with ``yield`` in a coroutine, this is a non-blocking analogue to `time.sleep` (which should not be used in coroutines because it is blocking):: yield gen.sleep(0.5) Note that calling this function on its own does nothing; you must wait on the `.Future` it returns (usually by yielding it). """ f = Future() IOLoop.current().call_later(duration, lambda: f.set_result(None)) return f
def add_sockets(self, sockets): if self._io_loop is None: self._io_loop = IOLoop.current() for sock in sockets: self._sockets[sock.fileno()] = sock add_accept_handler(sock, self._handle_connection, io_loop=self._io_loop)
def chain_future(a: "Future[_T]", b: "Future[_T]") -> None: def copy(future: "Future[_T]") -> None: assert future is a if b.done(): return if hasattr(a, "exc_info") and a.exc_info() is not None: future_set_exc_info(b, a.exc_info()) elif a.exception() is not None: b.set_exception(a.exception()) else: b.set_result(a.result()) if isinstance(a, Future): future_add_done_callback(a, copy) else: from ioloop import IOLoop IOLoop.current().add_future(a, copy)
def add_sockets(self, sockets): if self._io_loop is None: self._io_loop = IOLoop.current() for sock in sockets: self._sockets[sock.fileno()] = sock add_accept_handler(sock, self._handle_connection, io_loop=self._io_loop)
def __init__(self, gen, result_future, first_yielded): self.gen = gen self.result_future = result_future self.future = _null_future self.running = False self.finished = False self.ioloop = IOLoop.current() if self.handle_yield(first_yielded): self.run()
def with_timeout(abstimeout, future, io_loop=None, quiet_exceptions=()): """Wraps a `.Future` in a timeout. Raises `TimeoutError` if the input future does not complete before ``timeout``, which may be specified in any form allowed by `.IOLoop.add_timeout` (i.e. a `datetime.timedelta` or an absolute time relative to `.IOLoop.time`) If the wrapped `.Future` fails after it has timed out, the exception will be logged unless it is of a type contained in ``quiet_exceptions`` (which may be an exception type or a sequence of types). Currently only supports Futures, not other `YieldPoint` classes. """ result = Future() chain_future(future, result) if io_loop is None: io_loop = IOLoop.current() def error_callback(future): try: future.result() except Exception as e: if not isinstance(e, quiet_exceptions): logging.error("Exception in Future %r after timeout", future, exc_info=True) def timeout_callback(): result.set_exception(TimeoutError("Timeout")) # In case the wrapped future goes on to fail, log it. future.add_done_callback(error_callback) timeout_handle = io_loop.call_at(abstimeout, timeout_callback) if isinstance(future, Future): # We know this future will resolve on the IOLoop, so we don't # need the extra thread-safety of IOLoop.add_future future.add_done_callback( lambda future: io_loop.remove_timeout(timeout_handle)) else: # concurrent.futures.Futures may resolve on any thread, so we # need to route them back to the IOLoop. def cancel_on_ioloop(fut): IOLoop.current().call_next_tick( lambda fut: IOLoop.current().remove_timeout(timeout_handle)) future.add_done_callback(cancel_on_ioloop) return result
def with_timeout(abstimeout, future, io_loop=None, quiet_exceptions=()): """Wraps a `.Future` in a timeout. Raises `TimeoutError` if the input future does not complete before ``timeout``, which may be specified in any form allowed by `.IOLoop.add_timeout` (i.e. a `datetime.timedelta` or an absolute time relative to `.IOLoop.time`) If the wrapped `.Future` fails after it has timed out, the exception will be logged unless it is of a type contained in ``quiet_exceptions`` (which may be an exception type or a sequence of types). Currently only supports Futures, not other `YieldPoint` classes. """ result = Future() chain_future(future, result) if io_loop is None: io_loop = IOLoop.current() def error_callback(future): try: future.result() except Exception as e: if not isinstance(e, quiet_exceptions): logging.error("Exception in Future %r after timeout", future, exc_info=True) def timeout_callback(): result.set_exception(TimeoutError("Timeout")) # In case the wrapped future goes on to fail, log it. future.add_done_callback(error_callback) timeout_handle = io_loop.call_at(abstimeout, timeout_callback) if isinstance(future, Future): # We know this future will resolve on the IOLoop, so we don't # need the extra thread-safety of IOLoop.add_future future.add_done_callback( lambda future: io_loop.remove_timeout(timeout_handle)) else: # concurrent.futures.Futures may resolve on any thread, so we # need to route them back to the IOLoop. def cancel_on_ioloop(fut): IOLoop.current().call_next_tick(lambda fut : IOLoop.current().remove_timeout(timeout_handle)) future.add_done_callback(cancel_on_ioloop) return result
def add_accept_handler(sock, callback, io_loop=None): if io_loop is None: io_loop = IOLoop.current() def accept_handler(fd, events): while True: try: connection, address = sock.accept() except socket.error as e: if e.args[0] in (errno.EWOULDBLOCK, errno.EAGAIN): return if e.args[0] == errno.ECONNABORTED: continue raise callback(connection, address) io_loop.add_handler(sock.fileno(), accept_handler, IOLoop.READ)
def __init__(self, gen, result_future, first_yielded): self.gen = gen self.result_future = result_future self.future = _null_future self.running = False self.finished = False # is coroutine over? self.had_exception = False self.io_loop = IOLoop.current() # For efficiency, we do not create a stack context until we # reach a YieldPoint (stack contexts are required for the historical # semantics of YieldPoints, but not for Futures). When we have # done so, this field will be set and must be called at the end # of the coroutine. if self.handle_yield(first_yielded): self.run() else: pass # future is not ready
def __init__(self, gen, result_future, first_yielded): self.gen = gen self.result_future = result_future self.future = _null_future self.running = False self.finished = False # is coroutine over? self.had_exception = False self.io_loop = IOLoop.current() # For efficiency, we do not create a stack context until we # reach a YieldPoint (stack contexts are required for the historical # semantics of YieldPoints, but not for Futures). When we have # done so, this field will be set and must be called at the end # of the coroutine. if self.handle_yield(first_yielded): self.run() else: pass # future is not ready
def callback_on_ioloop(fut): IOLoop.current().call_next_tick( lambda fut: callback(fut.result()))
def cancel_on_ioloop(fut): IOLoop.current().call_next_tick( lambda fut: IOLoop.current().remove_timeout(timeout_handle))
print('on header exception.') raise print(method, uri, version, self._address) remote_ip = self._address[0] self._request = HTTPRequest(connection=self, method=method, uri=uri, version=version, headers=headers, remote_ip=remote_ip) content_length = headers.get('Content-Length') if content_length: content_length = int(content_length) if content_length > self._stream.max_buffer_size(): print('Content-Length too long') raise self._stream.read_bytes(content_length, self._on_request_body) def _on_request_body(self, data): print('request body: %s' % data) self._request.body = data if self._request_callback: self._request_callback(self._request) if __name__ == '__main__': server = HTTPServer(None, io_loop=IOLoop.current()) server.listen(9999) IOLoop.instance().start()
def call_on_ioloop(fut): IOLoop.current().call_next_tick(lambda : self.run())
def cancel_on_ioloop(fut): IOLoop.current().call_next_tick(lambda fut : IOLoop.current().remove_timeout(timeout_handle))
def call_on_ioloop(fut): IOLoop.current().call_next_tick(lambda: self.run())
def callback_on_ioloop(fut): IOLoop.current().call_next_tick(lambda fut : callback(fut.result()))
if not version.startswith('HTTP/'): print('error http version') except: print('on header exception.') raise print(method, uri, version, self._address) remote_ip = self._address[0] self._request = HTTPRequest( connection=self, method=method, uri=uri, version=version, headers=headers, remote_ip=remote_ip) content_length = headers.get('Content-Length') if content_length: content_length = int(content_length) if content_length > self._stream.max_buffer_size(): print('Content-Length too long') raise self._stream.read_bytes(content_length, self._on_request_body) def _on_request_body(self, data): print('request body: %s' % data) self._request.body = data if self._request_callback: self._request_callback(self._request) if __name__ == '__main__': server = HTTPServer(None, io_loop=IOLoop.current()) server.listen(9999) IOLoop.instance().start()