Django Asyncronous задача, выполняемая синхронно с asgiref
Я получаю уведомления в моем Django приложении через API и мне нужно вернуть HTTP 200 до истечения 500 миллисекунд. Для этого мне нужно асинхронно запустить соответствующую задачу. Я использую для этого библиотеку asgiref
, все работает нормально, но я думаю, что на самом деле задача не выполняется асинхронно.
Майн виев
В этом представлении я получаю уведомления. Я установил 2 точки печати для проверки времени в журнале сервера.
@csrf_exempt
@api_view(('POST',))
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def IncommingMeliNotifications(request):
print('--------------------------- Received ---------------------')
notificacion = json.loads(request.body)
call_resource = async_to_sync(CallResource(notificacion))
print('--------------------------- Answered ---------------------')
return Response({}, template_name='assessments.html', status=status.HTTP_200_OK)
Вторичный вид
После получения уведомления я вызываю вторичное представление CallResource
, которое, как я ожидаю, будет выполняться асинхронно.
def CallResource(notificacion):
do things inside....
print('--------------------------- Secondary view ---------------------')
return 'ok'
Log results
Когда я проверяю журнал, я всегда получаю отпечатки в следующем порядке:
print('--------------------------- Received ---------------------')
print('--------------------------- Secondary view ---------------------')
print('--------------------------- Answered ---------------------')
Но я полагаю, что Secondary view
должен печататься последним, как:
print('--------------------------- Received ---------------------')
print('--------------------------- Answered ---------------------')
print('--------------------------- Secondary view ---------------------')
Что я здесь упускаю?
Любые подсказки приветствуются. Заранее спасибо.
async_to_sync
позволяет синхронному потоку останавливаться и ждать асинхронной функции, а не запускать синхронную функцию асинхронно.Поскольку вы не упомянули ASGI-сервер, похоже, что вы используете сервер разработки синхронизации
python manage.py runserver
.
Если это так, установите и запустите Daphne (из Django) вместо него.
pip install daphne
daphne myproject.asgi:application
- Вы можете создать асинхронную задачу при запуске ASGI-сервера.
# call_resource = async_to_sync(CallResource(notificacion))
loop = asyncio.get_event_loop()
task = loop.create_task(CallResource(notificacion))
- Асинхронная функция должна быть определена с помощью
async def
.
# def CallResource(notificacion):
async def CallResource(notificacion):