【问题标题】:Intermittent "Event loop stopped before Future completed."间歇性“事件循环在未来完成之前停止。”
【发布时间】:2020-10-09 14:41:21
【问题描述】:

在这个问题上我一直在扯头发

有问题的代码是此处开源项目的一部分:aiosmtpd(我的实际 FOSS 项目的分支,here

有问题的文件是这个:main.py

出现问题的代码在line 139 of main.py

这是一个sn-p:

...
from aiosmtpd.smtp import DATA_SIZE_DEFAULT, SMTP, __version__
...

...

    # args is the result of ArgumentParser.parse_args

    factory = partial(
        SMTP, args.handler,
        data_size_limit=args.size, enable_SMTPUTF8=args.smtputf8)

    ...

    server = loop.run_until_complete(
        loop.create_server(factory, host=args.host, port=args.port))

    ...

有时——也就是说,并非总是——代码在那个时候失败,RuntimeError: Event loop stopped before Future completed.

我的问题:

  1. 间歇性失败的原因可能是什么?

    在测试过程中有 10% 的时间失败了(使用 tox + nosetest2),但 90% 的时间顺利进行。

  2. 我应该如何检测和/或检查和/或断言以防止这种情况发生?

  3. “恢复”错误并重做操作的最佳策略是什么?


我将第 n 次强调 错误是间歇性发生的。很少,但经常足够让我觉得有必要追查根本原因。在出现错误后,如果我再次重新运行代码——立即或延迟后——几乎总是不会发生相同的错误。

【问题讨论】:

  • 在代码库的某处寻找对loop.stop() 的调用。您可能想要删除它们,因为它们与 run_until_complete 以及更现代的 asyncio.run 根本不兼容。
  • @user4815162342 不,在这两条有问题的行中没有loop.stop()factory 是一个简单的 partial 环绕另一个类,在该类中没有任何地方 loop.stop()。记得我反复强调“间歇”;代码中存在loop.stop() 将导致“始终”而不是“间歇”。
  • 我知道loop.stop() 没有出现在这些行中,但它很可能出现在代码库的其他地方,甚至可能出现在一个库中,它会在出现以下情况时停止循环无法处理的事件。除非 asyncio 中出现错误,否则消息发生的唯一方法是有人调用 loop.stop(),所以这就是我首先要寻找的。如果这没有显示任何内容,下一步将是注释 asyncio 以了解消息是如何到达而不事先调用loop.stop() - 但您更有可能找到@ 987654338@上一步。
  • @user4815162342 正如我之前评论的那样(我可能不够清楚,我的错)我已经从第 139 行追踪到。无处在从第 139 行调用的调用堆栈中,我是否找到了 loop.stop() 的任何实例。此外——我真的强调了这一点——错误只是间歇性地发生。含义:有时(实际上很少)会发生错误。大多数时候,代码运行没有任何问题。 loop.stop() 在调用堆栈中任何位置的存在都会导致不断的错误而不是间歇性的。
  • 没问题,很高兴问题得到解决!

标签: python-3.x python-asyncio


【解决方案1】:

除非 asyncio 中存在错误,否则该问题很可能是由隐藏在代码库某处的对 loop.stop() 的调用引起的。您可能想要删除或禁用它们,因为它们与 run_until_complete 以及更现代的 asyncio.run 根本不兼容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2014-12-31
    相关资源
    最近更新 更多