Opened 5 years ago
Closed 5 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:
- The synchronous blocking calls made from within the callback hooked to
request_finishedcould be made async using the sync_to_async adapter and this has to be documented appropriately.
(OR)
- The
send_responsemethod 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 , 5 years ago
| Cc: | added |
|---|---|
| Has patch: | unset |
comment:2 by , 5 years ago
| Type: | Uncategorized → Bug |
|---|
comment:3 by , 5 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
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.