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