1
1
"Thread-safe in-memory cache backend."
2
2
3
+ from contextlib import contextmanager
3
4
import time
4
5
try :
5
6
from django .utils .six .moves import cPickle as pickle
17
18
_locks = {}
18
19
19
20
21
+ @contextmanager
22
+ def dummy ():
23
+ """A context manager that does nothing special."""
24
+ yield
25
+
26
+
20
27
class LocMemCache (BaseCache ):
21
28
def __init__ (self , name , params ):
22
29
BaseCache .__init__ (self , params )
@@ -34,11 +41,11 @@ def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
34
41
return True
35
42
return False
36
43
37
- def get (self , key , default = None , version = None ):
44
+ def get (self , key , default = None , version = None , acquire_lock = True ):
38
45
key = self .make_key (key , version = version )
39
46
self .validate_key (key )
40
47
pickled = None
41
- with self ._lock .reader ():
48
+ with ( self ._lock .reader () if acquire_lock else dummy () ):
42
49
if not self ._has_expired (key ):
43
50
pickled = self ._cache [key ]
44
51
if pickled is not None :
@@ -47,7 +54,7 @@ def get(self, key, default=None, version=None):
47
54
except pickle .PickleError :
48
55
return default
49
56
50
- with self ._lock .writer ():
57
+ with ( self ._lock .writer () if acquire_lock else dummy () ):
51
58
try :
52
59
del self ._cache [key ]
53
60
del self ._expire_info [key ]
@@ -69,13 +76,13 @@ def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
69
76
self ._set (key , pickled , timeout )
70
77
71
78
def incr (self , key , delta = 1 , version = None ):
72
- value = self .get (key , version = version )
73
- if value is None :
74
- raise ValueError ("Key '%s' not found" % key )
75
- new_value = value + delta
76
- key = self .make_key (key , version = version )
77
- pickled = pickle .dumps (new_value , pickle .HIGHEST_PROTOCOL )
78
79
with self ._lock .writer ():
80
+ value = self .get (key , version = version , acquire_lock = False )
81
+ if value is None :
82
+ raise ValueError ("Key '%s' not found" % key )
83
+ new_value = value + delta
84
+ key = self .make_key (key , version = version )
85
+ pickled = pickle .dumps (new_value , pickle .HIGHEST_PROTOCOL )
79
86
self ._cache [key ] = pickled
80
87
return new_value
81
88
0 commit comments