Description
I'm using django-bmemcached
and python-binary-memcached
with django-brake
for rate limiting.
Occasionally, I'm getting the following exception:
File "/app/.heroku/python/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/app/.heroku/python/lib/python2.7/site-packages/brake/decorators.py", line 87, in _wrapped
_backend.count(func_name, request, ip, field, period)
File "/app/.heroku/python/lib/python2.7/site-packages/brake/backends/cachebe.py", line 65, in count
cache.set(key, (count, expiration), timeout=int(expiration - time.time()))
File "/app/.heroku/python/lib/python2.7/site-packages/django/core/cache/backends/memcached.py", line 91, in set
if not self._cache.set(key, value, self.get_backend_timeout(timeout)):
File "/app/.heroku/python/lib/python2.7/site-packages/bmemcached/client.py", line 161, in set
returns.append(server.set(key, value, time))
File "/app/.heroku/python/lib/python2.7/site-packages/bmemcached/protocol.py", line 506, in set
return self._set_add_replace('set', key, value, time)
File "/app/.heroku/python/lib/python2.7/site-packages/bmemcached/protocol.py", line 477, in _set_add_replace
time, str_to_bytes(key), value))
error: integer out of range for 'L' format code
It turns out that the problem is django-bmemcached
passing a value of -1
as the argument timeout
to python-binary-memcached
. The latter tries to pack this as an L
(unsigned long) into the struct, which of course fails for -1
.
The -1
comes from the following code in BaseMemcachedCache.get_backend_timeout()
:
elif int(timeout) == 0:
# Other cache backends treat 0 as set-and-expire. To achieve this
# in memcache backends, a negative timeout must be passed.
timeout = -1
The code before that indicates that it occures when an entry is set the moment it expires:
cache.set(key, (count, expiration), timeout=int(expiration - time.time()))
According to the docs, a timeout of 0 for cache.set() is valid and won't cache the value. However, that's apparently not how python-binary-memcached
works.
Here I get a bit lost, just starting to use these libraries for the first time. I'm already pretty confused which code comes from which library. Can you help me out?