python - 基于 asyncio 的库应该提供什么 API 来处理关键错误?

标签 python error-handling python-asyncio

我正在使用asyncio编写一个库。在某些情况下,它检测到严重错误并且无法继续。这不是错误,问题有外部原因。

常规库代码会引发异常。程序将默认终止,但调用者也有机会捕获异常并执行清理或某种重置。这就是我想要的,但不幸的是,异常在 asyncio 中不能以这种方式工作。更多相关内容: https://docs.python.org/3/library/asyncio-dev.html#detect-never-retrieved-exceptions

通知异步库用户有关问题的合理方法是什么?错误发生时可能会激活一些回调。用户可以进行必要的清理,然后在回调中退出。

但是默认操作应该是什么?取消当前任务?停止整个事件循环?调用sys.exit

最佳答案

一般来说,不需要特定于错误的回调。 Asyncio 完全支持跨协程内的 await 边界以及跨诸如同步和异步代码相遇的 run_until_complete 之类的调用传播异常。当有人等待你的协程时,你可以按照通常的方式引发异常。

一个陷阱是作为“后台任务”运行的协程。当此类协程失败时,可能会导致库无法使用,没有人会自动收到通知。这是 asyncio 中的一个已知缺陷(详细讨论请参阅 here),目前为 being addressed 。同时,您可以使用如下代码实现等效功能:

class Library:
    async def work_forever(self):
        loop = asyncio.get_event_loop()
        self._exit_future = loop.create_future()
        await self._exit_future

    async def stop_working(self):
        self._cleanup()
        self._exit_future.set_result(None)

    async def _failed(self):
        self._cleanup()
        self._exit_future.set_exception(YourExceptionType())

    def _cleanup(self):
        # cancel the worker tasks
        ...

work_forever 类似于 serve_forever ,可以由 main() 协程等待的调用,甚至可以直接传递给 asyncio.run()。在此设计中,库可能会检测到错误状态并传播异常,或者主程序(大概通过单独生成的协程)可以请求它干净退出。

关于python - 基于 asyncio 的库应该提供什么 API 来处理关键错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53676088/

相关文章:

python asyncio 从 3.4 迁移到 3.5+

python - 在python中实现协程

python - 为什么 __prepare__ 将 name 和 bases 作为参数

python - 如何通过标准输入优化列表和字符串之间的比较代码 - 性能很重要

ios - 为什么Objective-C中的 "try catch"会导致内存泄漏?

python - Python [Errno 13]-保存用户打开的文件时的异常处理

node.js - 如何找到异步 nodejs 程序失败的源代码行

python-asyncio - 检测客户端何时关闭来自 aiohttp 请求处理程序的连接

python - Django Rest Framework - 嵌套一对多的过滤器

python - 有人可以解释以下功能之间的速度差异吗?