1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 | try:
import memcache
except ImportError:
_MintCache = None
else:
class _MintCache(_Cache):
"Memcached cache backend the sequel."
def __init__(self, server, params):
_Cache.__init__(self, params)
self._cache = memcache.Client(server.split(';'))
def get(self, key, default=None):
key = self.scrub_key( key )
val = self._cache.get(key)
if val is None:
val = default
else:
try:
stale_after,val = pickle.loads(val)
now = time.time()
if now > stale_after:
cache_log( "stale, refreshing" )
self.set( key, val, 60 ) # the old val will now last for 60 additional secs
val = default
except:
pass
return val
def set(self, key, value, timeout=0):
key = self.scrub_key( key )
if timeout is 0:
timeout = self.default_timeout
now = time.time()
val = pickle.dumps( ( now + timeout, value ), 2)
self._cache.set(key, val, 7*86400)
def delete(self, key):
key = self.scrub_key( key )
self._cache.delete(key)
|
Comments
Note that on line 23, val is assigned the default value.
This makes the caller who gets a near miss think it's an actual miss so that it takes the branch to re-fill the cache.
e.g.
spam = cache.get('key'): if spam is None: spam = "SPAM"*1000 cache.set('key', spam, 120)
The caller who gets a near miss (but only that caller) takes the "spam is None" branch.
#
Do you reckon this should get put either as an option or as default in trunk? Has anyone submitted a ticket?
#
I've posted an alternative version at http://www.djangosnippets.org/snippets/793/ which we found easier to use.
#