Opened 4 years ago

Closed 4 years ago

#32447 closed Bug (wontfix)

ORM query made in `request_finished` signal callback fails in ASGI

Reported by: Aditya N Owned by: nobody
Component: HTTP handling Version: 3.0
Severity: Normal Keywords: request_finished signal ASGI ORM query
Cc: gojeta.aditya@…, Aditya N Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When running Django with an ASGI server, any ORM query that's made inside a callback connected to the request_finished signal fails with an exception saying:

SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async

After inspecting code, I figured out that this was because the django.core.handlers.asgi.ASGIHandler class provides a send_response method which is natively async. This method subsequently fires the request_finished signal and since this happens from within an async context, Django complains and rightly so.

So the issue here is that this behaviour about the request_finished signal hasn't been documented and so it might come as a surprise to people when they try to run their code using an ASGI server. Also, any such ORM queries made from a callback hooked to the request_started signal works just fine without any modifications.

The solution to this problem could be as follows:

  1. The synchronous blocking calls made from within the callback hooked to request_finished could be made async using the sync_to_async adapter and this has to be documented appropriately.

(OR)

  1. The send_response method could be made natively synchronous and converted into an async callable using the sync_to_async adapter wherein it would run in a background thread without blocking the event loop but this could have performance implications.

If we can finalise on one of the above two or an even better one, I could send a patch for the same.

Change History (3)

comment:1 by Aditya N, 4 years ago

Cc: Aditya N added
Has patch: unset

comment:2 by Aditya N, 4 years ago

Type: UncategorizedBug

comment:3 by Mariusz Felisiak, 4 years ago

Resolution: wontfix
Status: newclosed

Thanks for this ticket, however Django 3.0 is in extended support so it doesn't receive bugfixes anymore (except security fixes and data loss bugs). This issue was fixed in fc0fa72ff4cdbf5861a366e31cb8bbacd44da22d. I would strongly recommend to use Django 3.1+ which supports a fully asynchronous request path.

Note: See TracTickets for help on using tickets.
Back to Top