#33497: Database persistent connections do not work with ASGI in 4.0
-------------------------------------+-------------------------------------
     Reporter:  Stenkar              |                    Owner:  (none)
         Type:  New feature          |                   Status:  new
    Component:  Database layer       |                  Version:  4.0
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  ASGI, Database,      |             Triage Stage:  Accepted
  async                              |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Comment (by Florian Apolloner):

 I think there is a bit of a missunderstanding about this ticket and what
 the connection pool can do and how.

 First off, let me start with the initial description of the ticket, namely
 that persistent connections do not work with ASGI. Yes this is correct, is
 by design and will stay that way. The reason for this is that persistent
 connections as implemented in Django are basically persistent per thread
 identifier. With ASGI you basically get a new thread identifier per
 request and as such a new connection. The old connections are not getting
 cleaned up at all quickly resulting in an exhaustion of the connection
 limits.

 With the connection pool you are actually able to reuse those connections
 because they don't have a thread affinity anymore. If not this is yet
 another bug that should be fixed, but I think this should work and so far
 noone has shown any logs or an example project to the contrary and I will
 also not waste my time if there is no effort in helping by providing logs
 etc…

 What will not work though is that the connection pool will make your
 server magically be massively concurrently. The way connection handling in
 Django currently works is that the connection is checked out at the first
 SQL operation in a request and returned at the **end** of the request. So
 the max size of the pool basically sets a hard limit on how many request
 you can handle in parallel holding a connection. This is basically
 equivalent to using no connection pool inside Django and pgbouncer in
 `pool_mode = session`. If you have only have a handful of views that are
 accessing the database and also doing a lot of work (ie the response time
 is long) then you probably can manually close the connection mid view
 which will return the connection to the pool allowing for more concurrent
 requests.

 A small example of this might look like this ([syntax] errors to be
 expected):
 {{{#!python
 from django.db import connection

 async def my_long_running_view(request):
     my_tasks = list(Task.objects.all()) # Force the query to execute now
     connection.close() # Close the connection and as such release back to
 the pool
     for task in tasks: # Note: I know that this could be done in parallel
 as well, but that is besides the point here
         await some_long_running_operation(task)

     # Queries here will checkout a new connection from the pool
 }}}

 So yes, I do think that the connection pool in Django does solve the
 problem of persistent connections not working in ASGI, what it doesn't do
 is providing a mode that behaves like pgbouncers `pool_mode =
 transaction`. This would certainly be a worthwile improvement but given
 the limited feedback on pooling so far I never bothered implementing it.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/33497#comment:51>
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 django-updates+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/django-updates/010701958e45ec68-0fdcaf4d-02a0-4515-aefb-36f1dc457d90-000000%40eu-central-1.amazonses.com.

Reply via email to