引发 asyncio.CancelledError 后无法使用 sync_to_async 装饰器
Cannot use sync_to_async decorator after raising asyncio.CancelledError
import asyncio
from asgiref.sync import sync_to_async
@sync_to_async
def sync_func():
print("sync_func() was CALLED (good!)")
async def async_func():
print("async_func() was CALLED (good!)")
async def test(excep_type: type = asyncio.CancelledError):
print(f"\nException Type: {excep_type}")
try:
raise excep_type
except:
await async_func()
try:
await sync_func()
except asyncio.CancelledError:
print("sync_func() was CANCELLED (bad!)")
asyncio.run(test(excep_type=ValueError))
asyncio.run(test())
你好。我有一个简单的例子
test
是一个异步函数,它除了引发提供的错误类型外什么都不做,然后在内部等待 async_func
和 sync_func
。
sync_func
是一个与 asgiref 包的 sync_to_async
异步的同步函数。
运行 这给出了以下输出:
Exception Type: <class 'ValueError'>
async_func() was CALLED (good!)
sync_func() was CALLED (good!)
Exception Type: <class 'asyncio.exceptions.CancelledError'>
async_func() was CALLED (good!)
sync_func() was CANCELLED (bad!)
在第一种情况下,引发了 ValueError
并且在异常子句中,我可以像往常一样等待 async_func
和 sync_func
。
但是在第二种情况下,我的行为出乎我的意料。我应该能够像往常一样等待 sync_func
,但它会引发 asyncio.CancelledError
,如打印输出所示。
实际上,除了更改最初由异常子句引发和捕获的错误类型外,我没有更改两次调用之间的任何内容。然而,引发的错误类型似乎产生了影响。
这意味着现实世界,我不能在任何 clean-up activity of cancelled tasks
中使用 sync_to_async
包装的异步函数
这似乎是由 sync_to_async
装饰器引起的,因为 async_func
运行良好。
我做错了什么?
这是 asgiref 3.3.1 中引入的 sync_to_async
中的错误。
https://github.com/django/asgiref/issues/247
这可以使用内置的 asyncio 功能来解决,或者,如果这不可能,则将失败的协程包装在 create_task
中。
import asyncio
from asgiref.sync import sync_to_async
@sync_to_async
def sync_func():
print("sync_func() was CALLED (good!)")
async def async_func():
print("async_func() was CALLED (good!)")
async def test(excep_type: type = asyncio.CancelledError):
print(f"\nException Type: {excep_type}")
try:
raise excep_type
except:
await async_func()
try:
await sync_func()
except asyncio.CancelledError:
print("sync_func() was CANCELLED (bad!)")
asyncio.run(test(excep_type=ValueError))
asyncio.run(test())
你好。我有一个简单的例子
test
是一个异步函数,它除了引发提供的错误类型外什么都不做,然后在内部等待async_func
和sync_func
。sync_func
是一个与 asgiref 包的sync_to_async
异步的同步函数。
运行 这给出了以下输出:
Exception Type: <class 'ValueError'>
async_func() was CALLED (good!)
sync_func() was CALLED (good!)
Exception Type: <class 'asyncio.exceptions.CancelledError'>
async_func() was CALLED (good!)
sync_func() was CANCELLED (bad!)
在第一种情况下,引发了 ValueError
并且在异常子句中,我可以像往常一样等待 async_func
和 sync_func
。
但是在第二种情况下,我的行为出乎我的意料。我应该能够像往常一样等待 sync_func
,但它会引发 asyncio.CancelledError
,如打印输出所示。
实际上,除了更改最初由异常子句引发和捕获的错误类型外,我没有更改两次调用之间的任何内容。然而,引发的错误类型似乎产生了影响。
这意味着现实世界,我不能在任何 clean-up activity of cancelled tasks
中使用sync_to_async
包装的异步函数
这似乎是由 sync_to_async
装饰器引起的,因为 async_func
运行良好。
我做错了什么?
这是 asgiref 3.3.1 中引入的 sync_to_async
中的错误。
https://github.com/django/asgiref/issues/247
这可以使用内置的 asyncio 功能来解决,或者,如果这不可能,则将失败的协程包装在 create_task
中。