【问题标题】:Why would a timeout avoid a tornado hang?为什么超时会避免龙卷风挂起?
【发布时间】:2016-02-11 14:58:03
【问题描述】:

在 Tornado 协程中等待来自 ThreadPoolExecutorconcurrent.futures.Future 有时会为我挂起:

def slowinc(x):
    time.sleep(0.1)
    return x + 1
yield tp_executor.submit(slowinc, 1)  # sometimes hangs

当我添加超时时,它可能会在超时期间挂起,但似乎在该时间之后实际上返回了正确的结果。

yield gen.with_timeout(timedelta(seconds=5), 
                       executor.submit(...))  # hangs for 5sec, then works

这只发生在较大的测试套件的上下文中,其中会发生许多不愉快的事情(子进程在中途终止)。这个错误几乎肯定与这个令人不快的环境有关,而不是严格意义上的 Tornado 的错。但是,我相信我已经尽可能地隔离了这些不愉快的事情。

因此,对于细微的错误和缺乏简单的可重复示例,我深表歉意。我希望失败超时的奇怪行为实际上导致成功有助于隔离我的问题。

临时解决方案

到目前为止,我的解决方案如下:

while not future.done():
    try:
        yield gen.with_timeout(timedelta(seconds=1), future)
    except gen.TimeoutError:
        pass

result = future.result()

这解决了我的直接问题,除了偶尔的一秒钟延迟之外,它完全可以使用。尽管如此,我仍然对这种行为感到困惑,并且很好奇我正在做什么奇怪的事情来触发这种行为。

更新

上面的超时解决方案适用于 Tornado 4.2 和 4.3 下的 Python 3.4,但@ben-darnell 的答案中的timeout 解决方案和PeriodicCallback 解决方案都不能解决 Python 2.7 Tornado 4.2 或 4.3 下的这个问题.

【问题讨论】:

  • 执行者是ThreadPoolExecutor还是ProcessPoolExecutor
  • 编辑声明这是来自 ThreadPoolExecutor。
  • 在 python 2.7 中出现同样的问题。 @gen.coroutine 在某个时间后抛出 WebSocketClosedError

标签: python tornado


【解决方案1】:

我没有完整的解决方案,但我想我可以提供一个更简单的解决方法:启动一个在短时间内什么都不做的后台 PeriodicCallbackPeriodicCallback(lambda: None, 500).start()。这将确保 IOLoop 定期唤醒,而不会干扰您的所有 yield executor.submit() 调用。

症状表明问题在于add_callback的“唤醒”行为:https://github.com/tornadoweb/tornado/blob/d9c5bc8fb6530a03ebbb6da667e26685b8eee0ea/tornado/ioloop.py#L929-L944

此代码在 Tornado 4.3 (https://github.com/tornadoweb/tornado/pull/1511/files) 中已更改。如果您使用的是 4.3,请查看 4.2 中是否仍然存在问题。你的“不愉快”环境中的任何事情都会导致thread.get_ident() 的行为与龙卷风预期的不同吗?

有报告称 Windows 上的唤醒器“管道”存在(罕见)问题:https://github.com/tornadoweb/tornado/pull/1364

【讨论】:

  • 不管怎样,这个问题存在于 linux 上的 Tornado 4.2.1
  • Tornado 4.2.1 和 4.3.0 上的 Python 2.7(我之前在 3.4 上)这个解决方案和问题中提出的超时解决方案都失败了。关于这可能是@ben-darnell 的任何其他想法?调试和隔离这被证明是一个挑战。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多