我有一个Django视图,它调用一个asgiref.sync.async_to_sync
函数来查询一个远程API--我正在更新一组雇员的工资单数据。在其中一个调用中,我必须再次访问DB,所以有一个asgiref.sync.sync_to_async
修饰函数来收集数据。我使用asyncio.gather
并发地运行雇员更新函数调用,但是这会无限期地挂起,甚至不会进入DB调用--即使我在收集列表中只有一个调用也会发生这种情况。2等待函数工作正常。3所有的东西都在Uvicorn下作为ASGI应用程序运行。4有什么想法吗?
这是一个最小的复制品:
@sync_to_async
def _get_database_employee_payslips(employee_data):
print(f"Entering DB function")
return employee_data
@async_to_sync
async def get_full_employees_data(_, __):
print(f"This works")
ret = await _get_database_employee_payslips({'id': 1625841})
print(f"Got {ret}")
print(f"This doesn't")
ret = await asyncio.gather(*[
_get_database_employee_payslips({'id': employee_id})
for employee_id in [1625841]
], return_exceptions=True)
print(f"We're hung in the above call")
return ret
和结果:
INFO 2022-09-27 14:20:20,234 on 10776 140271592661440 Application startup complete.
DEBUG 2022-09-27 14:20:22,163 middleware 10776 140271484180032 process_request
DEBUG 2022-09-27 14:20:22,163 model_factory 10776 140271484180032 No maximum request body size is set, continuing.
DEBUG 2022-09-27 14:20:22,183 model_factory 10776 140271484180032 Created new request model with pk 161dfa90-4082-4ef1-8ab0-84d613c25550
This works
Entering DB function
Got {'id': 1625841}
This doesn't
环境:
- WSL2基因
- Ubuntu 22.04.1语言
- Python 3.10.4语言
Python包(只是看起来相关的包):
aiohttp==3.8.3
aiosignal==1.2.0
anyio==3.6.1
asgiref==3.5.2
async-timeout==4.0.2
asyncio==3.4.3
Django==4.1.1
uvicorn==0.18.3
uvloop==0.17.0
uWSGI==2.0.20
1条答案
按热度按时间hmae6n7t1#
这似乎是一个已知的问题--嵌套
async_to_sync
和sync_to_async
会使调用无限期地挂起,请参见https://code.djangoproject.com/ticket/32409