I'm receiving notification in my Django app via API and I should return HTTP 200 before 500 milliseconds. To achieve that I should run the related task asyncronously. I'm using asgiref library for it, everything runs ok but I think is not actualy running asyncronously.
Main viev
In this view I receive the notificacions. I set 2 Print points to check timming in the server log.
@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)
Secondary view
After receiving the notification I call the secondary view CallResource, which I expect to run asyncronusly.
def CallResource(notificacion):
do things inside....
print('--------------------------- Secondary view ---------------------')
return 'ok'
Log results
When I check the log, I always get the prints in the following order:
print('--------------------------- Received ---------------------')
print('--------------------------- Secondary view ---------------------')
print('--------------------------- Answered ---------------------')
But I suppose that the Secondary viewshould be the last to print, as:
print('--------------------------- Received ---------------------')
print('--------------------------- Answered ---------------------')
print('--------------------------- Secondary view ---------------------')
What am I missing here?
I'm reading the documentation github.com/django/asgiref and as far as I can tell this should be the paradigm I'm working on:
If the outermost layer of your program is synchronous, then all async code run through AsyncToSync will run in a per-call event loop in arbitrary sub-threads, while all thread_sensitive code will run in the main thread.
Any clues welcome. Thanks in advance.
CodePudding user response:
async_to_synclets a sync thread stop and wait for an async function, not run a sync function asynchronously.Since you didn't mention an ASGI server, it appears you are running the sync development server
python manage.py runserver.
If so, install and run Daphne (from Django) instead.
pip install daphne
daphne myproject.asgi:application
- You can create an async task when running an ASGI server.
# call_resource = async_to_sync(CallResource(notificacion))
loop = asyncio.get_event_loop()
task = loop.create_task(CallResource(notificacion))
- An async function should be defined with
async def.
# def CallResource(notificacion):
async def CallResource(notificacion):
