通过龙卷风中附加在IOLoop上的回调回写。

问题描述 投票:0回答:1

有一个棘手的post handler,有时会花很多时间(取决于输入值),有时不会。

我想要的是每当1秒过后就回写,动态分配响应。

def post():
    def callback():
        self.write('too-late')
        self.finish()

    timeout_obj = IOLoop.current().add_timeout(
        dt.timedelta(seconds=1),
        callback,
    )

    # some asynchronous operations

    if not self.request.connection.stream.closed():
        self.write('here is your response')
        self.finish()
        IOLoop.current().remove_timeout(timeout_obj)

事实证明,我不能从内部的 callback.

即使是引发异常,也会被内部上下文所抑制,不会通过 post 的方法。

还有其他方法可以达到目的吗?

谢谢你了。

更新2020-05-15我发现类似的 疑问

谢谢 @ionut-ticus, 使用 with_timeout() 是更方便。

经过一番尝试,我想我真的很接近我要找的东西了。

def wait(fn):
    @gen.coroutine
    @wraps(fn)
    def wrap(*args):
        try:
            result = yield gen.with_timeout(
                    dt.timedelta(seconds=20),
                    IOLoop.current().run_in_executor(None, fn, *args),
            )
            raise gen.Return(result)
        except gen.TimeoutError:
            logging.error('### TOO LONG')
            raise gen.Return('Next time, bro')
    return wrap


@wait
def blocking_func(item):
    time.sleep(30)
    # this is not a Subprocess.
    # It is a file IO and DB
    return 'we are done here'
  1. 还不确定,应该 wait() 被包裹着的装饰者迂回曲折?

  2. 有些时候,在连环夺宝的 blocking_func()可以有另一个 线程池执行器. 我有个担心,如果不把 "我的 "变成全局性的,然后传递给 "我的",这能行吗?龙卷风's run_in_executor()?

龙卷风: v5.1.1

python asynchronous callback tornado python-asyncio
1个回答
2
投票

以下是一个使用实例 tornado.gen.with_timeout. 请记住,任务需要是async,否则IOLoop会被阻塞,无法处理超时。

@gen.coroutine
def async_task():
    # some async code

@gen.coroutine
def get(self):
    delta = datetime.timedelta(seconds=1)
    try:
        task = self.async_task()
        result = yield gen.with_timeout(delta, task)
        self.write("success")
    except gen.TimeoutError:
        self.write("timeout")

1
投票

我建议使用 https:/github.comaio-libsasync-timeout。:

import asyncio
import async_timeout

def post():
    try:
        async with async_timeout.timeout(1):
            # some asynchronous operations

            if not self.request.connection.stream.closed():
                self.write('here is your response')
                self.finish()
                IOLoop.current().remove_timeout(timeout_obj)
    except asyncio.TimeoutError:
        self.write('too-late')
        self.finish()
© www.soinside.com 2019 - 2024. All rights reserved.