Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Unified Diff: third_party/google-endpoints/dogpile/cache/api.py

Issue 2666783008: Add google-endpoints to third_party/. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/google-endpoints/dogpile/cache/api.py
diff --git a/third_party/google-endpoints/dogpile/cache/api.py b/third_party/google-endpoints/dogpile/cache/api.py
new file mode 100644
index 0000000000000000000000000000000000000000..dbab2db384928103741141408739aac66dc0379f
--- /dev/null
+++ b/third_party/google-endpoints/dogpile/cache/api.py
@@ -0,0 +1,207 @@
+import operator
+from ..util.compat import py3k
+
+
+class NoValue(object):
+ """Describe a missing cache value.
+
+ The :attr:`.NO_VALUE` module global
+ should be used.
+
+ """
+ @property
+ def payload(self):
+ return self
+
+ if py3k:
+ def __bool__(self): # pragma NO COVERAGE
+ return False
+ else:
+ def __nonzero__(self): # pragma NO COVERAGE
+ return False
+
+NO_VALUE = NoValue()
+"""Value returned from ``get()`` that describes
+a key not present."""
+
+
+class CachedValue(tuple):
+ """Represent a value stored in the cache.
+
+ :class:`.CachedValue` is a two-tuple of
+ ``(payload, metadata)``, where ``metadata``
+ is dogpile.cache's tracking information (
+ currently the creation time). The metadata
+ and tuple structure is pickleable, if
+ the backend requires serialization.
+
+ """
+ payload = property(operator.itemgetter(0))
+ """Named accessor for the payload."""
+
+ metadata = property(operator.itemgetter(1))
+ """Named accessor for the dogpile.cache metadata dictionary."""
+
+ def __new__(cls, payload, metadata):
+ return tuple.__new__(cls, (payload, metadata))
+
+ def __reduce__(self):
+ return CachedValue, (self.payload, self.metadata)
+
+
+class CacheBackend(object):
+ """Base class for backend implementations."""
+
+ key_mangler = None
+ """Key mangling function.
+
+ May be None, or otherwise declared
+ as an ordinary instance method.
+
+ """
+
+ def __init__(self, arguments): # pragma NO COVERAGE
+ """Construct a new :class:`.CacheBackend`.
+
+ Subclasses should override this to
+ handle the given arguments.
+
+ :param arguments: The ``arguments`` parameter
+ passed to :func:`.make_registry`.
+
+ """
+ raise NotImplementedError()
+
+ @classmethod
+ def from_config_dict(cls, config_dict, prefix):
+ prefix_len = len(prefix)
+ return cls(
+ dict(
+ (key[prefix_len:], config_dict[key])
+ for key in config_dict
+ if key.startswith(prefix)
+ )
+ )
+
+ def has_lock_timeout(self):
+ return False
+
+ def get_mutex(self, key):
+ """Return an optional mutexing object for the given key.
+
+ This object need only provide an ``acquire()``
+ and ``release()`` method.
+
+ May return ``None``, in which case the dogpile
+ lock will use a regular ``threading.Lock``
+ object to mutex concurrent threads for
+ value creation. The default implementation
+ returns ``None``.
+
+ Different backends may want to provide various
+ kinds of "mutex" objects, such as those which
+ link to lock files, distributed mutexes,
+ memcached semaphores, etc. Whatever
+ kind of system is best suited for the scope
+ and behavior of the caching backend.
+
+ A mutex that takes the key into account will
+ allow multiple regenerate operations across
+ keys to proceed simultaneously, while a mutex
+ that does not will serialize regenerate operations
+ to just one at a time across all keys in the region.
+ The latter approach, or a variant that involves
+ a modulus of the given key's hash value,
+ can be used as a means of throttling the total
+ number of value recreation operations that may
+ proceed at one time.
+
+ """
+ return None
+
+ def get(self, key): # pragma NO COVERAGE
+ """Retrieve a value from the cache.
+
+ The returned value should be an instance of
+ :class:`.CachedValue`, or ``NO_VALUE`` if
+ not present.
+
+ """
+ raise NotImplementedError()
+
+ def get_multi(self, keys): # pragma NO COVERAGE
+ """Retrieve multiple values from the cache.
+
+ The returned value should be a list, corresponding
+ to the list of keys given.
+
+ .. versionadded:: 0.5.0
+
+ """
+ raise NotImplementedError()
+
+ def set(self, key, value): # pragma NO COVERAGE
+ """Set a value in the cache.
+
+ The key will be whatever was passed
+ to the registry, processed by the
+ "key mangling" function, if any.
+ The value will always be an instance
+ of :class:`.CachedValue`.
+
+ """
+ raise NotImplementedError()
+
+ def set_multi(self, mapping): # pragma NO COVERAGE
+ """Set multiple values in the cache.
+
+ ``mapping`` is a dict in which
+ the key will be whatever was passed
+ to the registry, processed by the
+ "key mangling" function, if any.
+ The value will always be an instance
+ of :class:`.CachedValue`.
+
+ When implementing a new :class:`.CacheBackend` or cutomizing via
+ :class:`.ProxyBackend`, be aware that when this method is invoked by
+ :meth:`.Region.get_or_create_multi`, the ``mapping`` values are the
+ same ones returned to the upstream caller. If the subclass alters the
+ values in any way, it must not do so 'in-place' on the ``mapping`` dict
+ -- that will have the undesirable effect of modifying the returned
+ values as well.
+
+ .. versionadded:: 0.5.0
+
+ """
+ raise NotImplementedError()
+
+ def delete(self, key): # pragma NO COVERAGE
+ """Delete a value from the cache.
+
+ The key will be whatever was passed
+ to the registry, processed by the
+ "key mangling" function, if any.
+
+ The behavior here should be idempotent,
+ that is, can be called any number of times
+ regardless of whether or not the
+ key exists.
+ """
+ raise NotImplementedError()
+
+ def delete_multi(self, keys): # pragma NO COVERAGE
+ """Delete multiple values from the cache.
+
+ The key will be whatever was passed
+ to the registry, processed by the
+ "key mangling" function, if any.
+
+ The behavior here should be idempotent,
+ that is, can be called any number of times
+ regardless of whether or not the
+ key exists.
+
+ .. versionadded:: 0.5.0
+
+ """
+ raise NotImplementedError()

Powered by Google App Engine
This is Rietveld 408576698