Opened 2 months ago
Last modified 4 weeks ago
#35757 closed Bug
memcached.PyMemcacheCache reentrancy problem with ASGI-based runserver — at Version 6
Reported by: | Harm Verhagen | Owned by: | |
---|---|---|---|
Component: | Core (Cache system) | Version: | 5.1 |
Severity: | Normal | Keywords: | asgi, async |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I found that using memcached.PyMemcacheCache
with runserver has reentrancy problems.
I implemented a json api in django, when issuing multiple request simultaneously from javascript, the requests sometimes crash.
I have urls that do something like this.
from django.core.cache import cache def example_url(request): cache.incr("some key", 1) # count requests return JsonResponse(data=data, status=201)
When issuing 5-10 requests simultaneously on a runserver, it often (not always) get this crash
File "..../views/api.py", line 2512, in example_url cache.incr("some key", 1) File "./venv/lib/python3.12/site-packages/django/core/cache/backends/memcached.py", line 110, in incr val = self._cache.incr(key, delta) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "./venv/lib/python3.12/site-packages/pymemcache/client/hash.py", line 350, in incr return self._run_cmd("incr", key, False, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "./venv/lib/python3.12/site-packages/pymemcache/client/hash.py", line 322, in _run_cmd return self._safely_run_func(client, func, default_val, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "./venv/lib/python3.12/site-packages/pymemcache/client/hash.py", line 211, in _safely_run_func result = func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "./venv/lib/python3.12/site-packages/pymemcache/client/base.py", line 827, in incr results = self._misc_cmd([cmd], b"incr", noreply) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "./venv/lib/python3.12/site-packages/pymemcache/client/base.py", line 1291, in _misc_cmd buf, line = _reader(self.sock, buf) ^^^^^^^^^^^^^^^^^^^^^^^ File "./venv/lib/python3.12/site-packages/pymemcache/client/base.py", line 1658, in _readline buf = _recv(sock, RECV_SIZE) ^^^^^^^^^^^^^^^^^^^^^^ File "./venv/lib/python3.12/site-packages/pymemcache/client/base.py", line 1750, in _recv return sock.recv(size) OSError: [Errno 9] Bad file descriptor
The following code looked a bit suspicious.
cache.backends.memcached.py:99 BaseMemcachedCache
def close(self, **kwargs): # Many clients don't clean up connections properly. self._cache.disconnect_all()
Doesn't this race? closing a all connections, might close a connection of a parallel request that was just opened but not yet finished.
Notes
I'm not putting a heavy load on runserver, its a simple javascript app, that happens to do 10 requests on a single page. Django should be able to handle that, also in a dev environment
Workaround
Adding the --noasgi
option seems to help.
./manage.py runserver --noasgi
Weird enough the (to me) more obvious, --nothreading
option does _not_ help. That crashes in the same way.
NB: this workaround breaks django channels, so if you have websockets in your app, then this workaround
is not usable.
Version info
Django==5.1.1 pymemcache==4.0.0 python 3.12.6
Change History (6)
comment:1 by , 2 months ago
Description: | modified (diff) |
---|
comment:2 by , 2 months ago
Description: | modified (diff) |
---|
comment:3 by , 2 months ago
Description: | modified (diff) |
---|
comment:4 by , 2 months ago
Summary: | memcached.PyMemcacheCache reentrancy problem (OSError: [Errno 9] Bad file descriptor) → memcached.PyMemcacheCache reentrancy problem with ASGI-based runserver |
---|
comment:5 by , 2 months ago
Description: | modified (diff) |
---|
comment:6 by , 2 months ago
Description: | modified (diff) |
---|