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 ---------------------')

Что я здесь упускаю?

Любые подсказки приветствуются. Заранее спасибо.

  1. async_to_sync позволяет синхронному потоку останавливаться и ждать асинхронной функции, а не запускать синхронную функцию асинхронно.

  2. Поскольку вы не упомянули ASGI-сервер, похоже, что вы используете сервер разработки синхронизации python manage.py runserver.
    Если это так, установите и запустите Daphne (из Django) вместо него.

pip install daphne
daphne myproject.asgi:application
  1. Вы можете создать асинхронную задачу при запуске ASGI-сервера.
# call_resource = async_to_sync(CallResource(notificacion))
loop = asyncio.get_event_loop()
task = loop.create_task(CallResource(notificacion))
  1. Асинхронная функция должна быть определена с помощью async def.
# def CallResource(notificacion):
async def CallResource(notificacion):
Вернуться на верх