Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1import operator 

2 

3from ..util.compat import py3k 

4 

5 

6class NoValue(object): 

7 """Describe a missing cache value. 

8 

9 The :attr:`.NO_VALUE` module global 

10 should be used. 

11 

12 """ 

13 

14 @property 

15 def payload(self): 

16 return self 

17 

18 def __repr__(self): 

19 """Ensure __repr__ is a consistent value in case NoValue is used to 

20 fill another cache key. 

21 

22 """ 

23 return "<dogpile.cache.api.NoValue object>" 

24 

25 if py3k: 

26 

27 def __bool__(self): # pragma NO COVERAGE 

28 return False 

29 

30 else: 

31 

32 def __nonzero__(self): # pragma NO COVERAGE 

33 return False 

34 

35 

36NO_VALUE = NoValue() 

37"""Value returned from ``get()`` that describes 

38a key not present.""" 

39 

40 

41class CachedValue(tuple): 

42 """Represent a value stored in the cache. 

43 

44 :class:`.CachedValue` is a two-tuple of 

45 ``(payload, metadata)``, where ``metadata`` 

46 is dogpile.cache's tracking information ( 

47 currently the creation time). The metadata 

48 and tuple structure is pickleable, if 

49 the backend requires serialization. 

50 

51 """ 

52 

53 payload = property(operator.itemgetter(0)) 

54 """Named accessor for the payload.""" 

55 

56 metadata = property(operator.itemgetter(1)) 

57 """Named accessor for the dogpile.cache metadata dictionary.""" 

58 

59 def __new__(cls, payload, metadata): 

60 return tuple.__new__(cls, (payload, metadata)) 

61 

62 def __reduce__(self): 

63 return CachedValue, (self.payload, self.metadata) 

64 

65 

66class CacheBackend(object): 

67 """Base class for backend implementations.""" 

68 

69 key_mangler = None 

70 """Key mangling function. 

71 

72 May be None, or otherwise declared 

73 as an ordinary instance method. 

74 

75 """ 

76 

77 def __init__(self, arguments): # pragma NO COVERAGE 

78 """Construct a new :class:`.CacheBackend`. 

79 

80 Subclasses should override this to 

81 handle the given arguments. 

82 

83 :param arguments: The ``arguments`` parameter 

84 passed to :func:`.make_registry`. 

85 

86 """ 

87 raise NotImplementedError() 

88 

89 @classmethod 

90 def from_config_dict(cls, config_dict, prefix): 

91 prefix_len = len(prefix) 

92 return cls( 

93 dict( 

94 (key[prefix_len:], config_dict[key]) 

95 for key in config_dict 

96 if key.startswith(prefix) 

97 ) 

98 ) 

99 

100 def has_lock_timeout(self): 

101 return False 

102 

103 def get_mutex(self, key): 

104 """Return an optional mutexing object for the given key. 

105 

106 This object need only provide an ``acquire()`` 

107 and ``release()`` method. 

108 

109 May return ``None``, in which case the dogpile 

110 lock will use a regular ``threading.Lock`` 

111 object to mutex concurrent threads for 

112 value creation. The default implementation 

113 returns ``None``. 

114 

115 Different backends may want to provide various 

116 kinds of "mutex" objects, such as those which 

117 link to lock files, distributed mutexes, 

118 memcached semaphores, etc. Whatever 

119 kind of system is best suited for the scope 

120 and behavior of the caching backend. 

121 

122 A mutex that takes the key into account will 

123 allow multiple regenerate operations across 

124 keys to proceed simultaneously, while a mutex 

125 that does not will serialize regenerate operations 

126 to just one at a time across all keys in the region. 

127 The latter approach, or a variant that involves 

128 a modulus of the given key's hash value, 

129 can be used as a means of throttling the total 

130 number of value recreation operations that may 

131 proceed at one time. 

132 

133 """ 

134 return None 

135 

136 def get(self, key): # pragma NO COVERAGE 

137 """Retrieve a value from the cache. 

138 

139 The returned value should be an instance of 

140 :class:`.CachedValue`, or ``NO_VALUE`` if 

141 not present. 

142 

143 """ 

144 raise NotImplementedError() 

145 

146 def get_multi(self, keys): # pragma NO COVERAGE 

147 """Retrieve multiple values from the cache. 

148 

149 The returned value should be a list, corresponding 

150 to the list of keys given. 

151 

152 .. versionadded:: 0.5.0 

153 

154 """ 

155 raise NotImplementedError() 

156 

157 def set(self, key, value): # pragma NO COVERAGE 

158 """Set a value in the cache. 

159 

160 The key will be whatever was passed 

161 to the registry, processed by the 

162 "key mangling" function, if any. 

163 The value will always be an instance 

164 of :class:`.CachedValue`. 

165 

166 """ 

167 raise NotImplementedError() 

168 

169 def set_multi(self, mapping): # pragma NO COVERAGE 

170 """Set multiple values in the cache. 

171 

172 ``mapping`` is a dict in which 

173 the key will be whatever was passed 

174 to the registry, processed by the 

175 "key mangling" function, if any. 

176 The value will always be an instance 

177 of :class:`.CachedValue`. 

178 

179 When implementing a new :class:`.CacheBackend` or cutomizing via 

180 :class:`.ProxyBackend`, be aware that when this method is invoked by 

181 :meth:`.Region.get_or_create_multi`, the ``mapping`` values are the 

182 same ones returned to the upstream caller. If the subclass alters the 

183 values in any way, it must not do so 'in-place' on the ``mapping`` dict 

184 -- that will have the undesirable effect of modifying the returned 

185 values as well. 

186 

187 .. versionadded:: 0.5.0 

188 

189 """ 

190 raise NotImplementedError() 

191 

192 def delete(self, key): # pragma NO COVERAGE 

193 """Delete a value from the cache. 

194 

195 The key will be whatever was passed 

196 to the registry, processed by the 

197 "key mangling" function, if any. 

198 

199 The behavior here should be idempotent, 

200 that is, can be called any number of times 

201 regardless of whether or not the 

202 key exists. 

203 """ 

204 raise NotImplementedError() 

205 

206 def delete_multi(self, keys): # pragma NO COVERAGE 

207 """Delete multiple values from the cache. 

208 

209 The key will be whatever was passed 

210 to the registry, processed by the 

211 "key mangling" function, if any. 

212 

213 The behavior here should be idempotent, 

214 that is, can be called any number of times 

215 regardless of whether or not the 

216 key exists. 

217 

218 .. versionadded:: 0.5.0 

219 

220 """ 

221 raise NotImplementedError()