#33625: Under ASGI, PyLibMCCache closes memcached connection after every request
-------------------------------------+-------------------------------------
     Reporter:  Anders Kaseorg       |                    Owner:  Pablo
         Type:                       |  Montepagano
  Cleanup/optimization               |                   Status:  assigned
    Component:  Core (Cache system)  |                  Version:  4.0
     Severity:  Normal               |               Resolution:
     Keywords:  asgi, async          |             Triage Stage:  Accepted
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Old description:

> When I run an application that uses
> `django.core.cache.backends.memcached.PyMemcacheCache` with WSGI under
> Gunicorn, it makes a single connection to memcached and leaves it open,
> as I expect.
>
> But when I run it with ASGI under uvicorn, it makes a different
> connection to memcached for every request and immediately closes it. That
> is, #11331/#15324 has returned. This at least adds undesirable latency,
> and may also eventually lead to connection failures as described in
> #11331.
>
> I think this happens because e3f6e18513224c8ad081e5a19da641f49b0b43da
> switched the thread-local cache objects to task-local cache objects. That
> was justified in #31253 by “a potential race condition if two coroutines
> touch the same cache object at exactly the same time”. But that
> justification doesn’t make sense: two coroutines ''cannot'' be running
> the same ''synchronous'' code on the same thread at the same time, so
> thread-local objects were already safe.
>
> Now that asynchronous cache backend support is being developed, the
> argument is slightly different—but it seems obvious to expect that any
> asynchronous cache backend should at least properly support concurrent
> use from multiple asynchronous tasks on the same thread, so thread-local
> objects should still be safe.

New description:

 When I run an application that uses
 `django.core.cache.backends.memcached.PyLibMCCache` with WSGI under
 Gunicorn, it makes a single connection to memcached and leaves it open, as
 I expect.

 But when I run it with ASGI under uvicorn, it makes a different connection
 to memcached for every request and immediately closes it. That is,
 #11331/#15324 has returned. This at least adds undesirable latency, and
 may also eventually lead to connection failures as described in #11331.

 I think this happens because e3f6e18513224c8ad081e5a19da641f49b0b43da
 switched the thread-local cache objects to task-local cache objects. That
 was justified in #31253 by “a potential race condition if two coroutines
 touch the same cache object at exactly the same time”. But that
 justification doesn’t make sense: two coroutines ''cannot'' be running the
 same ''synchronous'' code on the same thread at the same time, so thread-
 local objects were already safe.

 Now that asynchronous cache backend support is being developed, the
 argument is slightly different—but it seems obvious to expect that any
 asynchronous cache backend should at least properly support concurrent use
 from multiple asynchronous tasks on the same thread, so thread-local
 objects should still be safe.

--

Comment (by Anders Kaseorg):

 We don’t need a new pool. Both
 [https://sendapatch.se/projects/pylibmc/pooling.html pylibmc] and
 [https://pymemcache.readthedocs.io/en/latest/getting_started.html#using-a
 -client-pool pymemcache] already have one.

 It seems to me it’d be best to leave pooling up to the backend library,
 because it’s in a better position to know what kinds of concurrency are
 safe.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/33625#comment:7>
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/01070181b5d947b0-189a4d09-0ba8-4723-b967-3a804c98862d-000000%40eu-central-1.amazonses.com.

Reply via email to