示例#1
0
    def wrapper(*args, **kwargs):
        future = TracebackFuture()

        if replace_callback and 'callback' in kwargs:
            # 调用的参数有callback,不实用future使用异步callback
            callback = kwargs.pop('callback')
            IOLoop.current().add_future(
                future, lambda future: callback(future.result()))

        try:
            # 调用实际的处理函数如果返回GeneratorType,那么进入Runner类循环执行直到终止
            result = func(*args, **kwargs)
        except (Return, StopIteration) as e:
            result = _value_from_stopiteration(e)
        except Exception:
            future.set_exc_info(sys.exc_info())
            return future
        else:
            # 生成器
            if isinstance(result, GeneratorType):
                # Inline the first iteration of Runner.run.  This lets us
                # avoid the cost of creating a Runner when the coroutine
                # never actually yields, which in turn allows us to
                # use "optional" coroutines in critical path code without
                # performance penalty for the synchronous case.
                try:
                    orig_stack_contexts = stack_context._state.contexts
                    # 返回第一个Future,异步调用返回的Future,
                    # 在异步调用成功后会将这个Future给set_done
                    yielded = next(result)
                    if stack_context._state.contexts is not orig_stack_contexts:
                        yielded = TracebackFuture()
                        yielded.set_exception(
                            stack_context.StackContextInconsistentError(
                                'stack_context inconsistency (probably caused '
                                'by yield within a "with StackContext" block)')
                        )
                except (StopIteration, Return) as e:
                    future.set_result(_value_from_stopiteration(e))
                except Exception:
                    future.set_exc_info(sys.exc_info())
                else:
                    Runner(result, future, yielded)
                try:
                    # 进入Runner,返回
                    return future
                finally:
                    # Subtle memory optimization: if next() raised an exception,
                    # the future's exc_info contains a traceback which
                    # includes this stack frame.  This creates a cycle,
                    # which will be collected at the next full GC but has
                    # been shown to greatly increase memory usage of
                    # benchmarks (relative to the refcount-based scheme
                    # used in the absence of cycles).  We can avoid the
                    # cycle by clearing the local variable after we return it.
                    future = None
        future.set_result(result)
        return future
示例#2
0
    def handle_yield(self, yielded):
        # Lists containing YieldPoints require stack contexts;
        # other lists are handled in convert_yielded.
        if _contains_yieldpoint(yielded):
            yielded = multi(yielded)

        if isinstance(yielded, YieldPoint):
            # YieldPoints are too closely coupled to the Runner to go
            # through the generic convert_yielded mechanism.
            self.future = TracebackFuture()

            def start_yield_point():
                try:
                    yielded.start(self)
                    if yielded.is_ready():
                        self.future.set_result(yielded.get_result())
                    else:
                        self.yield_point = yielded
                except Exception:
                    self.future = TracebackFuture()
                    self.future.set_exc_info(sys.exc_info())

            if self.stack_context_deactivate is None:
                # Start a stack context if this is the first
                # YieldPoint we've seen.
                with stack_context.ExceptionStackContext(
                        self.handle_exception) as deactivate:
                    self.stack_context_deactivate = deactivate

                    def cb():
                        start_yield_point()
                        self.run()

                    self.io_loop.add_callback(cb)
                    return False
            else:
                start_yield_point()
        else:
            try:
                self.future = convert_yielded(yielded)
            except BadYieldError:
                self.future = TracebackFuture()
                self.future.set_exc_info(sys.exc_info())

        if not self.future.done() or self.future is moment:

            def inner(f):
                # Break a reference cycle to speed GC.
                f = None  # noqa
                self.run()

            self.io_loop.add_future(self.future, inner)
            return False
        return True
示例#3
0
    def handle_yield(self, yielded):
        # Lists containing YieldPoints require stack contexts;
        # other lists are handled via multi_future in convert_yielded.
        if (isinstance(yielded, list) and
                any(isinstance(f, YieldPoint) for f in yielded)):
            yielded = Multi(yielded)
        elif (isinstance(yielded, dict) and
              any(isinstance(f, YieldPoint) for f in yielded.values())):
            yielded = Multi(yielded)

        if isinstance(yielded, YieldPoint):
            # YieldPoints are too closely coupled to the Runner to go
            # through the generic convert_yielded mechanism.
            self.future = TracebackFuture()

            def start_yield_point():
                try:
                    yielded.start(self)
                    if yielded.is_ready():
                        self.future.set_result(
                            yielded.get_result())
                    else:
                        self.yield_point = yielded
                except Exception:
                    self.future = TracebackFuture()
                    self.future.set_exc_info(sys.exc_info())

            if self.stack_context_deactivate is None:
                # Start a stack context if this is the first
                # YieldPoint we've seen.
                with stack_context.ExceptionStackContext(
                        self.handle_exception) as deactivate:
                    self.stack_context_deactivate = deactivate

                    def cb():
                        start_yield_point()
                        self.run()
                    self.io_loop.add_callback(cb)
                    return False
            else:
                start_yield_point()
        else:
            try:
                self.future = convert_yielded(yielded)
            except BadYieldError:
                self.future = TracebackFuture()
                self.future.set_exc_info(sys.exc_info())

        if not self.future.done() or self.future is moment:
            self.io_loop.add_future(
                self.future, lambda f: self.run())
            return False
        return True
示例#4
0
 def run():
     try:
         result = func()
     except Exception:
         future_cell[0] = TracebackFuture()
         future_cell[0].set_exc_info(sys.exc_info())
     else:
         if is_future(result):
             future_cell[0] = result
         else:
             future_cell[0] = TracebackFuture()
             future_cell[0].set_result(result)
     self.add_future(future_cell[0], lambda future: self.stop())
示例#5
0
    def handle_yield(self, yielded):
        # 返回True已经完成,False表示Future未完成,添加到ioloop中
        # Lists containing YieldPoints require stack contexts;
        # other lists are handled in convert_yielded.
        # 处理 yield list or dict 情况
        if _contains_yieldpoint(yielded):
            yielded = multi(yielded)

        if isinstance(yielded, YieldPoint):
            # YieldPoints are too closely coupled to the Runner to go
            # through the generic convert_yielded mechanism.
            self.future = TracebackFuture()

            def start_yield_point():
                try:
                    yielded.start(self)
                    if yielded.is_ready():
                        self.future.set_result(yielded.get_result())
                    else:
                        self.yield_point = yielded
                except Exception:
                    self.future = TracebackFuture()
                    self.future.set_exc_info(sys.exc_info())

            if self.stack_context_deactivate is None:
                # Start a stack context if this is the first
                # YieldPoint we've seen.
                with stack_context.ExceptionStackContext(
                        self.handle_exception) as deactivate:
                    self.stack_context_deactivate = deactivate

                    def cb():
                        start_yield_point()
                        self.run()

                    self.io_loop.add_callback(cb)
                    return False
            else:
                start_yield_point()
        else:
            # Future情况,为r = yield fetch()之类返回的Future
            try:
                self.future = convert_yielded(yielded)
            except BadYieldError:
                self.future = TracebackFuture()
                self.future.set_exc_info(sys.exc_info())

        if not self.future.done() or self.future is moment:
            self.io_loop.add_future(self.future, lambda f: self.run())
            return False
        return True
示例#6
0
    def handle_yield(self, yielded):
        if isinstance(yielded, list):
            if all(is_future(f) for f in yielded):
                yielded = multi_future(yielded)
            else:
                yielded = Multi(yielded)
        elif isinstance(yielded, dict):
            if all(is_future(f) for f in yielded.values()):
                yielded = multi_future(yielded)
            else:
                yielded = Multi(yielded)

        if isinstance(yielded, YieldPoint):
            self.future = TracebackFuture()

            def start_yield_point():
                try:
                    yielded.start(self)
                    if yielded.is_ready():
                        self.future.set_result(yielded.get_result())
                    else:
                        self.yield_point = yielded
                except Exception:
                    self.future = TracebackFuture()
                    self.future.set_exc_info(sys.exc_info())

            if self.stack_context_deactivate is None:
                # Start a stack context if this is the first
                # YieldPoint we've seen.
                with stack_context.ExceptionStackContext(
                        self.handle_exception) as deactivate:
                    self.stack_context_deactivate = deactivate

                    def cb():
                        start_yield_point()
                        self.run()

                    self.io_loop.add_callback(cb)
                    return False
            else:
                start_yield_point()
        elif is_future(yielded):
            self.future = yielded
            if not self.future.done() or self.future is moment:
                self.io_loop.add_future(self.future, lambda f: self.run())
                return False
        else:
            self.future = TracebackFuture()
            self.future.set_exception(
                BadYieldError("yielded unknown object %r" % (yielded, )))
        return True
示例#7
0
文件: tests.py 项目: zjjott/html
        def mock_fetch(request, callback=None, raise_error=True, **kwargs):
            """mock 掉RESTfulAsyncClient的fetch函数,使之不再发起向外请求
            并且响应始终是固定的
            """
            future = TracebackFuture()
            if callback is not None:

                def handle_future(future):
                    """future的回调,单元测试里一般会挂上self.top"""
                    response = future.result()
                    self.io_loop.add_callback(callback, response)

                future.add_done_callback(handle_future)

            def immediately_done():
                """立即完成future"""
                buf = StringIO()
                buf.write(
                    json.dumps({  # 思索。。这里好像只能写死,要传参的话得在_request上再打一层
                        "ok": True,
                        "mock": True,
                        'user': {
                            "id": "1",
                            "username": "******",
                        }
                    }))
                response = HTTPResponse(request, 200, buffer=buf)
                future.set_result(response)

            self.io_loop.add_callback(immediately_done)
            return future
示例#8
0
    def method(self, *args, **kwargs):
        #loop = self.get_io_loop()
        loop = ioloop.IOLoop.current()
        callback = kwargs.pop('callback', None)

        if callback:
            if not callable(callback):
                raise callback_type_error
            future = None
        else:
            future = TracebackFuture()

        def call_method():
            # Runs on child greenlet.
            try:
                result = sync_method(self, *args, **kwargs)    #   用fun传对象调用方法
                if callback:
                    # Schedule callback(result, None) on main greenlet.
                    loop.add_callback(functools.partial(
                        callback, result, None))
                else:
                    # Schedule future to be resolved on main greenlet.
                    loop.add_callback(functools.partial(
                        future.set_result, result))
            except Exception as e:
                if callback:
                    loop.add_callback(functools.partial(
                        callback, None, e))
                else:
                    loop.add_callback(functools.partial(
                        future.set_exc_info, sys.exc_info()))

        # Start running the operation on a greenlet.
        greenlet.greenlet(call_method).switch()
        return future
示例#9
0
    def find_one(self, **kwargs):
        """Returns future.

        Executes collection's find_one method based on keyword args
        maps result ( dict to instance ) and return future

        Example::

           manager = EntityManager(Product)
           product_saved = yield manager.find_one(_id=object_id)

         """
        future = TracebackFuture()

        def handle_response(result, error):
            if error:
                future.set_exception(error)
            else:
                instance = self.__entity()
                instance.map_dict(result)
                future.set_result(instance)

        self.__collection.find_one(kwargs, callback=handle_response)

        return future
示例#10
0
    def start_tls(self, server_side, ssl_options, server_hostname=None):
        if not isinstance(ssl_options, SSL.Context):
            raise ValueError("ssl_options is not SSL.Context")

        _socket = self.detach()
        _socket = SSL.Connection(ssl_options, _socket)
        if server_side:
            _socket.set_accept_state()
        else:
            _socket.set_connect_state()
            if server_hostname:
                _socket.set_tlsext_host_name(server_hostname.encode("idna"))

        orig_close_callback = self._close_callback
        self._close_callback = None

        future = TracebackFuture()
        ssl_stream = MicroProxySSLIOStream(_socket,
                                           server_hostname=server_hostname,
                                           ssl_options=ssl_options,
                                           io_loop=self.io_loop)

        def close_callback():
            if not future.done():
                future.set_exception(ssl_stream.error or StreamClosedError())
            if orig_close_callback is not None:
                orig_close_callback()

        ssl_stream.set_close_callback(close_callback)
        ssl_stream._ssl_connect_callback = lambda: future.set_result(ssl_stream)
        ssl_stream.max_buffer_size = self.max_buffer_size
        ssl_stream.read_chunk_size = self.read_chunk_size
        return future
示例#11
0
def coroutine_run():
    """
    执行协程
    """
    try:
        result = consume_mq()
    except Exception:
        future = TracebackFuture()
        future.set_exc_info(sys.exc_info())
    else:
        assert isinstance(result, Future)
        future = result

    def consumer_finish(f):
        """
        重新启动ioloop回调
        :param f:
        """
        if f.exc_info() is not None:
            logger.warn(f.exc_info())
        elif f.exception() is not None:
            logger.warn(f.exception())

        IOLoop.current().add_callback(coroutine_run)

    IOLoop.current().add_future(future, consumer_finish)
示例#12
0
 def run():
     try:
         result = func()
         if result is not None:
             from tornado.gen import convert_yielded
             result = convert_yielded(result)
     except Exception:
         future_cell[0] = TracebackFuture()
         future_cell[0].set_exc_info(sys.exc_info())
     else:
         if is_future(result):
             future_cell[0] = result
         else:
             future_cell[0] = TracebackFuture()
             future_cell[0].set_result(result)
     self.add_future(future_cell[0], lambda future: self.stop())
示例#13
0
    def __init__(self, io_loop, request, on_message_callback=None,
                 compression_options=None):
        self.compression_options = compression_options
        self.connect_future = TracebackFuture()
        self.protocol = None
        self.read_future = None
        self.read_queue = collections.deque()
        self.key = base64.b64encode(os.urandom(16))
        self._on_message_callback = on_message_callback

        scheme, sep, rest = request.url.partition(':')
        scheme = {'ws': 'http', 'wss': 'https'}[scheme]
        request.url = scheme + sep + rest
        request.headers.update({
            'Upgrade': 'websocket',
            'Connection': 'Upgrade',
            'Sec-WebSocket-Key': self.key,
            'Sec-WebSocket-Version': '13',
        })
        if self.compression_options is not None:
            # Always offer to let the server set our max_wbits (and even though
            # we don't offer it, we will accept a client_no_context_takeover
            # from the server).
            # TODO: set server parameters for deflate extension
            # if requested in self.compression_options.
            request.headers['Sec-WebSocket-Extensions'] = (
                'permessage-deflate; client_max_window_bits')

        self.tcp_client = TCPClient(io_loop=io_loop)
        super(WebSocketClientConnection, self).__init__(
            io_loop, None, request, lambda: None, self._on_http_response,
            104857600, self.tcp_client, 65536)
示例#14
0
    def send_request(self, request):
        method = request.method
        data = request.body
        headers = {'Content-Type': 'application/json'}
        future = TracebackFuture()

        def process_response_future(response):
            if response.exc_info() is not None:
                future.set_exc_info(response.exc_info())

            elif response.exception() is not None:
                future.set_exception(response.exception())

            else:
                result = response.result()
                code = result.code
                body = (result.body or b'').decode('utf8')
                future.set_result(process_response(code, body))

        request = tornado.httpclient.HTTPRequest(
            request.url,
            method=method,
            body=data,
            headers=headers,
            request_timeout=self.client.timeout)

        response_future = self.http.fetch(request, raise_error=False)
        response_future.add_done_callback(process_response_future)

        return future
示例#15
0
def http_retry(client,
               request,
               raise_error=True,
               attempts=5,
               retry_wait=1,
               **kwargs):
    attempt = 1
    future = TracebackFuture()
    ioloop = IOLoop.current()

    def _do_request(attempt):
        http_future = client.fetch(request, raise_error=False, **kwargs)
        http_future.add_done_callback(partial(handle_response, attempt))

    def handle_response(attempt, future_response):
        attempt += 1
        result = future_response.result()
        if result.error and\
           attempt <= 5 and\
           result.code >= 500 and\
           result.code <= 599:
            logging.error(result.error)
            logging.error(result.body)
            return ioloop.call_later(retry_wait, lambda: _do_request(attempt))
        else:
            if raise_error and result.error:
                return future.set_exception(result.error)
        future.set_result(result)

    _do_request(attempt)
    return future
示例#16
0
    def invoke(self, *args):
        """异步调用redis相关接口

        :param args: 多条redis指令
        """
        #默认开启multi
        active_trans = True

        write_buf = _chain_cmds(active_trans, *args)
        future = TracebackFuture()

        def handle_resp(resp):
            f = resp.get(_RESP_FUTURE) or future
            err = resp.get(RESP_ERR)
            result = resp.get(RESP_RESULT)

            if err:
                f.set_exception(err)
            else:
                f.set_result(result)

        with NullContext():
            if self.__conn is None:
                self.__conn = _RedisConnection(self.__io_loop, write_buf, handle_resp, self.__uri, self.__password)
                self.__conn.connect(future, self.__uri, active_trans, len(args))
            else:
                self.__conn.write(write_buf, future, False, active_trans, len(args))
        return future
示例#17
0
    def write(self, data, callback=None):
        """Write the given data to this stream.

        If ``callback`` is given, we call it when all of the buffered write
        data has been successfully written to the stream. If there was
        previously buffered write data and an old write callback, that
        callback is simply overwritten with this new callback.
        """
        assert isinstance(data, bytes_type)
        self._check_closed()
        # We use bool(_write_buffer) as a proxy for write_buffer_size>0,
        # so never put empty strings in the buffer.
        if data:
            # Break up large contiguous strings before inserting them in the
            # write buffer, so we don't have to recopy the entire thing
            # as we slice off pieces to send to the socket.
            WRITE_BUFFER_CHUNK_SIZE = 128 * 1024
            for i in range(0, len(data), WRITE_BUFFER_CHUNK_SIZE):
                self._write_buffer.append(data[i:i + WRITE_BUFFER_CHUNK_SIZE])
        if callback is not None:
            self._write_callback = stack_context.wrap(callback)
            future = None
        else:
            future = self._write_future = TracebackFuture()
        if not self._connecting:
            self._handle_write()
            if self._write_buffer:
                self._add_io_state(self.io_loop.WRITE)
            self._maybe_add_error_listener()
        return future
示例#18
0
 def open(self):
     try:
         future = self._stream.open()
     except:
         exc_info = sys.exc_info()
         future = TracebackFuture()
         future.set_exc_info(exc_info)
     return future
示例#19
0
 def _set_read_callback(self, callback):
     assert self._read_callback is None, "Already reading"
     assert self._read_future is None, "Already reading"
     if callback is not None:
         self._read_callback = stack_context.wrap(callback)
     else:
         self._read_future = TracebackFuture()
     return self._read_future
示例#20
0
 def handle_exception(self, typ, value, tb):
     if not self.running and not self.finished:
         self.future = TracebackFuture()
         self.future.set_exc_info((typ, value, tb))
         self.run()
         return True
     else:
         return False
示例#21
0
    def submit(self, fn, *args, **kwargs):
        future = TracebackFuture()

        def _cb():
            chain_future(self._executor.submit(fn, *args, **kwargs), future)

        IOLoop.current().add_callback(_cb)
        return future
示例#22
0
文件: udp.py 项目: skripkar/noc
 def get_future(self):
     """
     Get future and start timeout task when needed
     """
     if not self.future or self.future.done():
         self.future = TracebackFuture()
         self.start_timeout()
     return self.future
示例#23
0
    def fetch(self, request, callback=None, raise_error=True, **kwargs):
        """Executes a request, asynchronously returning an `HTTPResponse`.

        The request may be either a string URL or an `HTTPRequest` object.
        If it is a string, we construct an `HTTPRequest` using any additional
        kwargs: ``HTTPRequest(request, **kwargs)``

        This method returns a `.Future` whose result is an
        `HTTPResponse`. By default, the ``Future`` will raise an
        `HTTPError` if the request returned a non-200 response code
        (other errors may also be raised if the server could not be
        contacted). Instead, if ``raise_error`` is set to False, the
        response will always be returned regardless of the response
        code.

        If a ``callback`` is given, it will be invoked with the `HTTPResponse`.
        In the callback interface, `HTTPError` is not automatically raised.
        Instead, you must check the response's ``error`` attribute or
        call its `~HTTPResponse.rethrow` method.
        """
        if self._closed:
            raise RuntimeError("fetch() called on closed AsyncHTTPClient")
        if not isinstance(request, HTTPRequest):
            request = HTTPRequest(url=request, **kwargs)
        # We may modify this (to add Host, Accept-Encoding, etc),
        # so make sure we don't modify the caller's object.  This is also
        # where normal dicts get converted to HTTPHeaders objects.
        request.headers = httputil.HTTPHeaders(request.headers)
        request = _RequestProxy(request, self.defaults)
        future = TracebackFuture()
        if callback is not None:
            callback = stack_context.wrap(callback)

            def handle_future(future):
                exc = future.exception()
                if isinstance(exc, HTTPError) and exc.response is not None:
                    response = exc.response
                elif exc is not None:
                    response = HTTPResponse(request,
                                            599,
                                            error=exc,
                                            request_time=time.time() -
                                            request.start_time)
                else:
                    response = future.result()
                self.io_loop.add_callback(callback, response)

            future.add_done_callback(handle_future)

        def handle_response(response):
            if raise_error and response.error:
                future.set_exception(response.error)
            else:
                future.set_result(response)

        self.fetch_impl(request, handle_response)
        return future
示例#24
0
def async (task, *args, **kwargs):
    future = TracebackFuture()
    callback = kwargs.pop("callback", None)
    if callback:
        IOLoop.instance().add_future(future,
                                     lambda future: callback(future.result()))
    result = task.delay(*args, **kwargs)
    IOLoop.instance().add_callback(_on_result, result, future)
    return future
示例#25
0
    def fetch(self, request, callback=None, **kwargs):
        """Executes a request, asynchronously returning an `HTTPResponse`.

        The request may be either a string URL or an `HTTPRequest` object.
        If it is a string, we construct an `HTTPRequest` using any additional
        kwargs: ``HTTPRequest(request, **kwargs)``

        # 注意,任何状态码不是200的都会抛出异常,需要自己捕获或者添加一个callback函数
        This method returns a `.Future` whose result is an
        `HTTPResponse`.  The ``Future`` will raise an `HTTPError` if
        the request returned a non-200 response code.

        如果添加了callback,那么不会有一个自动抛出的异常
        If a ``callback`` is given, it will be invoked with the `HTTPResponse`.
        In the callback interface, `HTTPError` is not automatically raised.
        Instead, you must check the response's ``error`` attribute or
        call its `~HTTPResponse.rethrow` method.
        """
        if not isinstance(request, HTTPRequest):
            request = HTTPRequest(url=request, **kwargs)
        # We may modify this (to add Host, Accept-Encoding, etc),
        # so make sure we don't modify the caller's object.  This is also
        # where normal dicts get converted to HTTPHeaders objects.
        # 构建headers,封装的一个类,处理起来比较方便
        request.headers = httputil.HTTPHeaders(request.headers)

        # request.request, request.defaults
        request = _RequestProxy(request, self.defaults)
        future = TracebackFuture()

        # 这个callback先放过
        if callback is not None:
            callback = stack_context.wrap(callback)

            def handle_future(future):
                exc = future.exception()
                if isinstance(exc, HTTPError) and exc.response is not None:
                    response = exc.response
                elif exc is not None:
                    response = HTTPResponse(
                        request, 599, error=exc,
                        request_time=time.time() - request.start_time)
                else:
                    response = future.result()
                self.io_loop.add_callback(callback, response)
            future.add_done_callback(handle_future)

        def handle_response(response):
            if response.error:
                future.set_exception(response.error)
            else:
                future.set_result(response)
        # rquest异步成功之后执行 handle_response(response)
        self.fetch_impl(request, handle_response)

        # 返回一个future类型
        return future
示例#26
0
 def start_yield_point():
     try:
         yielded.start(self)
         if yielded.is_ready():
             self.future.set_result(yielded.get_result())
         else:
             self.yield_point = yielded
     except Exception:
         self.future = TracebackFuture()
         self.future.set_exc_info(sys.exc_info())
    def __init__(self,
                 io_loop,
                 request,
                 on_message_callback=None,
                 compression_options=None):
        del request, on_message_callback, compression_options
        self.connect_future = TracebackFuture()
        self.written_messages = []

        io_loop.add_timeout(self.TIMEOUT, self._complete)
    def __init__(self, io_loop, request):
        self.connect_future = TracebackFuture()
        self.read_future = None
        self.read_queue = collections.deque()
        self.events = []

        self.tcp_client = TCPClient(io_loop=io_loop)
        super(EventSourceClient,
              self).__init__(io_loop, None, request, lambda: None,
                             self._on_http_response, 104857600,
                             self.tcp_client, 65536)
示例#29
0
    def read(self, callback=None):
        assert not self.reading(), 'Already reading'
        self.bytes_to_read = None
        if callback is not None:
            self._read_callback = stack_context.wrap(callback)
            future = None
        else:
            future = self._read_callback = TracebackFuture()
            future.add_done_callback(lambda f: f.exception())

        return future
示例#30
0
    def handle_yield(self, yielded):
        try:
            self.future = convert_yielded(yielded)
        except BadYieldError:
            self.future = TracebackFuture()
            self.future.set_exc_info(sys.exc_info())

        if not self.future.done() or self.future is moment:
            self.io_loop.add_future(self.future, lambda f: self.run())
            return False
        return True