【问题标题】:Tornado future result after timeout超时后龙卷风未来结果
【发布时间】:2025-11-22 21:10:03
【问题描述】:

这听起来可能有点奇怪,但是 Tornado 是否有可能在将 future 包装到超时后完成执行?

所以是这样的:

try:
    result = yield gen.with_timeout(time.time() + 1, future)
except gen.TimeoutError as e:
    print('Timed out!')

所以在这种情况下,future 在超时之前不会完成,但我希望它继续执行它所拥有的任何可调用对象。

换句话说,我希望能够将它与gen.WaitIterator 一起使用来获得一组期货的结果,如文档中所述:

如果您需要尽快得到每个future的结果,或者如果您需要一些future的结果,即使其他人产生错误,您可以使用WaitIterator

这正是我正在寻找的,我希望尽快获得每个未来的结果,因为我有一些任务需要比其他任务更长的时间,但有一个例外:那些缓慢的任务应该继续产生结果,以便我以后可以访问它们。

这可能吗?

【问题讨论】:

    标签: python tornado future coroutine concurrent.futures


    【解决方案1】:

    with_timeout不会取消底层Future,所以可以复用:

    future = do_something_async()
    while True:
        try:
            result = yield gen.with_timeout(timedelta(seconds=1), future)
            break
        except gen.TimeoutError:
            print('tick')
    

    将此与WaitIterator 结合起来有点棘手,因为在前一个完成之前,您不能再次调用WaitIterator.next

    还要考虑 Tornado 4.2 中引入的 Queue 类。这些通常可以生成比 WaitIterator 更简洁的代码(并且它们具有内置的超时支持而不是 with_timeout 包装器)。

    【讨论】:

    • 我想我可以使用 Queue 类来聚合来自不同 Web 服务的结果...通常,我希望能够从不同的 Web 服务(有些慢,有些快)收集结果并等待对于特定时间的所有结果。我应该在文档中查看队列示例(网络蜘蛛)吗?另外,是否可以改为concurrent.futures.ThreadPoolExecutor? (因为它也有concurrent.futures.wait
    • 是的,webspider 演示是我们使用队列的最佳示例。只需将每次获取的结果放在一个队列中,然后在“主”任务中读取它们。您不能将 AsyncHTTPClient 与 ThreadPoolExecutor 一起使用(您可以使用同步 HTTP 客户端,但这比非线程方式更昂贵)。