Opened 3 years ago
Last modified 6 weeks ago
#33625 assigned Cleanup/optimization
Under ASGI, PyLibMCCache closes memcached connection after every request — at Initial Version
Reported by: | Anders Kaseorg | Owned by: | nobody |
---|---|---|---|
Component: | Core (Cache system) | Version: | 4.0 |
Severity: | Normal | Keywords: | asgi, async |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
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.