#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.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/054.0dbdcd6ade3655099149ec6c290a636a%40djangoproject.com.

Reply via email to