The Django documentation states that “You can access the caches configured in the CACHES setting through a dict-like object: django.core.cache.caches. Repeated requests for the same alias in the same thread will return the same object.” However, I have a system that shows this statement is false. I am using Django 4.2 and the PyMemcache backend. When I access the cache from an asyncio Task using sync_to_async, a new PyMemcacheCache instance is created each time I run a new Task to access it. This problem is documented in #33625 (Under ASGI, PyLibMCCache closes memcached connection after every request) – Django.
But my problem is worse because the new cache connection created in every Task is not always closed. I cannot tell why it is sometimes closed and sometimes not, but a factor is spawning other asyncio Tasks from the Task accessing the cache. I can avoid the problem by removing one of the Tasks that I spawn immediately after accessing the cache, but I don’t understand why this influences it. I believe it has to do with the Context and ContextVar used to store the PyMemcacheCache instance. If I force the cache backend to use a threading.Local instead, then the backend keeps one connection open as the documentation states, and I no longer have a connection leak.
If the author of the above ticket is correct, a ContextVar is not necessary and is in fact causing unwanted behavior like opening a new connection to the cache every time and not always closing that connection, causing a leak.
Is anyone else experiencing this? Is there something I can do to safely access the cache from an async thread?
Thanks.