Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/dogpile/cache/api.py : 76%

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
3from ..util.compat import py3k
6class NoValue(object):
7 """Describe a missing cache value.
9 The :attr:`.NO_VALUE` module global
10 should be used.
12 """
14 @property
15 def payload(self):
16 return self
18 def __repr__(self):
19 """Ensure __repr__ is a consistent value in case NoValue is used to
20 fill another cache key.
22 """
23 return "<dogpile.cache.api.NoValue object>"
25 if py3k:
27 def __bool__(self): # pragma NO COVERAGE
28 return False
30 else:
32 def __nonzero__(self): # pragma NO COVERAGE
33 return False
36NO_VALUE = NoValue()
37"""Value returned from ``get()`` that describes
38a key not present."""
41class CachedValue(tuple):
42 """Represent a value stored in the cache.
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.
51 """
53 payload = property(operator.itemgetter(0))
54 """Named accessor for the payload."""
56 metadata = property(operator.itemgetter(1))
57 """Named accessor for the dogpile.cache metadata dictionary."""
59 def __new__(cls, payload, metadata):
60 return tuple.__new__(cls, (payload, metadata))
62 def __reduce__(self):
63 return CachedValue, (self.payload, self.metadata)
66class CacheBackend(object):
67 """Base class for backend implementations."""
69 key_mangler = None
70 """Key mangling function.
72 May be None, or otherwise declared
73 as an ordinary instance method.
75 """
77 def __init__(self, arguments): # pragma NO COVERAGE
78 """Construct a new :class:`.CacheBackend`.
80 Subclasses should override this to
81 handle the given arguments.
83 :param arguments: The ``arguments`` parameter
84 passed to :func:`.make_registry`.
86 """
87 raise NotImplementedError()
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 )
100 def has_lock_timeout(self):
101 return False
103 def get_mutex(self, key):
104 """Return an optional mutexing object for the given key.
106 This object need only provide an ``acquire()``
107 and ``release()`` method.
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``.
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.
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.
133 """
134 return None
136 def get(self, key): # pragma NO COVERAGE
137 """Retrieve a value from the cache.
139 The returned value should be an instance of
140 :class:`.CachedValue`, or ``NO_VALUE`` if
141 not present.
143 """
144 raise NotImplementedError()
146 def get_multi(self, keys): # pragma NO COVERAGE
147 """Retrieve multiple values from the cache.
149 The returned value should be a list, corresponding
150 to the list of keys given.
152 .. versionadded:: 0.5.0
154 """
155 raise NotImplementedError()
157 def set(self, key, value): # pragma NO COVERAGE
158 """Set a value in the cache.
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`.
166 """
167 raise NotImplementedError()
169 def set_multi(self, mapping): # pragma NO COVERAGE
170 """Set multiple values in the cache.
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`.
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.
187 .. versionadded:: 0.5.0
189 """
190 raise NotImplementedError()
192 def delete(self, key): # pragma NO COVERAGE
193 """Delete a value from the cache.
195 The key will be whatever was passed
196 to the registry, processed by the
197 "key mangling" function, if any.
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()
206 def delete_multi(self, keys): # pragma NO COVERAGE
207 """Delete multiple values from the cache.
209 The key will be whatever was passed
210 to the registry, processed by the
211 "key mangling" function, if any.
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.
218 .. versionadded:: 0.5.0
220 """
221 raise NotImplementedError()