#12399 closed (fixed)
memcached not working as expected when setting keys with a timeout > 30 days
Reported by: | houdinihound | Owned by: | nobody |
---|---|---|---|
Component: | Core (Cache system) | Version: | dev |
Severity: | Keywords: | cached_db session memcached | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Using the 'django.contrib.sessions.backends.cached_db' and setting SESSION_COOKIE_AGE to any number of seconds greater than 2592000 (i.e. > 30 days) with memcached does not to work as intended in that the session info is never sent back from the cache.
Memcached takes an 'expire_in_seconds' argument which can be up to 2592000 (30 days). For numbers greater than that it requires a Unix timestamp to set the expiry date.
Currently cached_db.py passes in settings.SESSION_COOKIE_AGE which is always a number of seconds. Consequently this works up to 30 days (2592000 seconds) but if SESSION_COOKIE_AGE is greater than that it does not.
To illustrate:
Memcached output with SESSION_COOKIE_AGE = 2592000 (i.e. 30 days):
<280 server listening (udp) <288 new client connection <288 get 4c35074ef4038b16a2db4f728324206a >288 END <288 set 4c35074ef4038b16a2db4f728324206a 1 2592000 334 >288 STORED <288 connection closed. <288 new client connection <288 get 4c35074ef4038b16a2db4f728324206a >288 sending key 4c35074ef4038b16a2db4f728324206a >288 END <288 connection closed. <288 new client connection <288 get 4c35074ef4038b16a2db4f728324206a >288 sending key 4c35074ef4038b16a2db4f728324206a >288 END
Works. After the initial store, the key is requested and sent as expected.
Now with SESSION_COOKIE_AGE = 2592001 (i.e. 30 days + 1 second):
<288 new client connection <288 get 4c35074ef4038b16a2db4f728324206a >288 END <288 set 4c35074ef4038b16a2db4f728324206a 1 2592001 337 >288 STORED <288 connection closed. <288 new client connection <288 get 4c35074ef4038b16a2db4f728324206a >288 END <288 set 4c35074ef4038b16a2db4f728324206a 1 2592001 337 >288 STORED <288 connection closed. <288 new client connection <288 get 4c35074ef4038b16a2db4f728324206a >288 END <288 set 4c35074ef4038b16a2db4f728324206a 1 2592001 337 >288 STORED <288 connection closed.
The key is initially stored, but each time it is requested it doesn't send the data but rather gets it from the db and keeps re-setting the same key each time.
I've patched load
and save
in cached_db.py to:
1) Check if memcached is being used
2) If so, check if settings.SESSION_COOKIE_AGE > 2592000
3) If so, add settings.SESSION_COOKIE_AGE to the unix timestamp (time.time()) and pass that to memcached.
which now works as expected when SESSION_COOKIE_AGE > 2592000:
<292 new client connection <292 get 4c35074ef4038b16a2db4f728324206a >292 END <292 set 4c35074ef4038b16a2db4f728324206a 1 1263689307 337 >292 STORED <292 connection closed. <292 new client connection <292 get 4c35074ef4038b16a2db4f728324206a >292 sending key 4c35074ef4038b16a2db4f728324206a >292 END <292 connection closed. <292 new client connection <292 get 4c35074ef4038b16a2db4f728324206a >292 sending key 4c35074ef4038b16a2db4f728324206a >292 END <292 connection closed.
Attachments (4)
Change History (15)
by , 15 years ago
Attachment: | patch1.diff added |
---|
comment:1 by , 15 years ago
Component: | Uncategorized → Cache system |
---|
by , 15 years ago
Attachment: | memcached-timeout-fixes.diff added |
---|
comment:2 by , 15 years ago
The patch above may be better because it works at the cache layer, hence fixing django.contrib.sessions.backends.cache, django.contrib.sessions.backends.cached_db, and in general, all the cache.set() calls with timeouts greater than 30 days.
comment:3 by , 15 years ago
Summary: | cached_db session backend and memcached not working as expected with expiry > 30 days → memcached not working as expected when setting keys with a timeout > 30 days |
---|
comment:4 by , 15 years ago
gciotta's patch seems to be a much better solution to this issue. Please ignore patch1.diff - too limited in scope.
comment:5 by , 15 years ago
Just to make the thing clearer: The issue raises when you set a key on memcached with a timeout > 30 days. In this case, memcache will happily consider it an absolute timestamp rather than a relative offset (as the cache layer is expecting), and your keys will expire immediately.
comment:6 by , 15 years ago
ups sorry, memcached-timeout-fixes.diff is better then django_memcache.patch
by , 15 years ago
Attachment: | memcached-timeout-fixes-with-tests-r12394.diff added |
---|
With tests, tested against today's r12394
comment:7 by , 15 years ago
milestone: | → 1.2 |
---|---|
Version: | 1.1 → SVN |
comment:8 by , 15 years ago
Triage Stage: | Unreviewed → Ready for checkin |
---|
comment:9 by , 15 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Fixes at cache layer, tested on 1.1.1 and trunk r12157