[Django] #32447: ORM query made in `request_finished` signal callback fails in ASGI

36 views
Skip to first unread message

Django

unread,
Feb 15, 2021, 1:23:29 PM2/15/21
to django-...@googlegroups.com
#32447: ORM query made in `request_finished` signal callback fails in ASGI
-------------------------------------+-------------------------------------
Reporter: Aditya N | Owner: nobody
Type: | Status: new
Uncategorized |
Component: HTTP | Version: 3.0
handling | Keywords: request_finished
Severity: Normal | signal ASGI ORM query
Triage Stage: | Has patch: 1
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
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)
2. 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.

--
Ticket URL: <https://code.djangoproject.com/ticket/32447>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 15, 2021, 1:24:31 PM2/15/21
to django-...@googlegroups.com
#32447: ORM query made in `request_finished` signal callback fails in ASGI
-------------------------------------+-------------------------------------
Reporter: Aditya N | Owner: nobody
Type: Uncategorized | Status: new
Component: HTTP handling | Version: 3.0
Severity: Normal | Resolution:
Keywords: request_finished | Triage Stage:
signal ASGI ORM query | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Aditya N):

* cc: Aditya N (added)
* has_patch: 1 => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/32447#comment:1>

Django

unread,
Feb 15, 2021, 1:25:46 PM2/15/21
to django-...@googlegroups.com
#32447: ORM query made in `request_finished` signal callback fails in ASGI
-------------------------------------+-------------------------------------
Reporter: Aditya N | Owner: nobody
Type: Bug | Status: new

Component: HTTP handling | Version: 3.0
Severity: Normal | Resolution:
Keywords: request_finished | Triage Stage:
signal ASGI ORM query | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Aditya N):

* type: Uncategorized => Bug


--
Ticket URL: <https://code.djangoproject.com/ticket/32447#comment:2>

Django

unread,
Feb 15, 2021, 2:18:27 PM2/15/21
to django-...@googlegroups.com
#32447: ORM query made in `request_finished` signal callback fails in ASGI
-------------------------------------+-------------------------------------
Reporter: Aditya N | Owner: nobody
Type: Bug | Status: closed

Component: HTTP handling | Version: 3.0
Severity: Normal | Resolution: wontfix

Keywords: request_finished | Triage Stage:
signal ASGI ORM query | Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => wontfix


Comment:

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.

--
Ticket URL: <https://code.djangoproject.com/ticket/32447#comment:3>

Reply all
Reply to author
Forward
0 new messages