From c9b797fb2c0e06acb34465e16e6c48bd6322d343 Mon Sep 17 00:00:00 2001 From: jonathan vanasco Date: Sat, 17 Oct 2015 20:52:23 -0400 Subject: [PATCH] replaced `keys` with `mapping` docs update on functions regarding how get_or_create_multi invokes set_multi --- docs/build/usage.rst | 8 ++++++-- dogpile/cache/api.py | 11 ++++++++++- dogpile/cache/proxy.py | 4 ++-- dogpile/cache/region.py | 7 +++++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/build/usage.rst b/docs/build/usage.rst index ffbe9a7..aaa3f92 100644 --- a/docs/build/usage.rst +++ b/docs/build/usage.rst @@ -479,9 +479,13 @@ Encoded ProxyBackend Example return self.value_decode(v) def set_multi(self, mapping): + """encode to a new dict to preserve unencoded values in-place when + called by `get_or_create_multi` + """ + mapping_set = {} for (k, v) in mapping.iteritems(): - mapping[k] = self.value_encode(v) - return self.proxied.set_multi(mapping) + mapping_set[k] = self.value_encode(v) + return self.proxied.set_multi(mapping_set) def get_multi(self, keys): results = self.proxied.get_multi(keys) diff --git a/dogpile/cache/api.py b/dogpile/cache/api.py index 85b6de1..92fa74d 100644 --- a/dogpile/cache/api.py +++ b/dogpile/cache/api.py @@ -152,11 +152,20 @@ class CacheBackend(object): def set_multi(self, mapping): # pragma NO COVERAGE """Set multiple values in the cache. - The key will be whatever was passed + ``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 diff --git a/dogpile/cache/proxy.py b/dogpile/cache/proxy.py index 7fe49d6..15c6b57 100644 --- a/dogpile/cache/proxy.py +++ b/dogpile/cache/proxy.py @@ -85,8 +85,8 @@ class ProxyBackend(CacheBackend): def get_multi(self, keys): return self.proxied.get_multi(keys) - def set_multi(self, keys): - self.proxied.set_multi(keys) + def set_multi(self, mapping): + self.proxied.set_multi(mapping) def delete_multi(self, keys): self.proxied.delete_multi(keys) diff --git a/dogpile/cache/region.py b/dogpile/cache/region.py index e46271d..ebaaa3f 100644 --- a/dogpile/cache/region.py +++ b/dogpile/cache/region.py @@ -670,6 +670,13 @@ class CacheRegion(object): The method uses the same approach as :meth:`.Region.get_multi` and :meth:`.Region.set_multi` to get and set values from the backend. + + If you are using a :class:`.CacheBackend` or :class:`.ProxyBackend` + that modifies values, take note this function invokes + ``.set_multi()`` for newly generated values using the same values it + returns to the calling function. A correct implementation of + ``.set_multi()`` will not modify values in-place on the submitted + ``mapping`` dict. :param keys: Sequence of keys to be retrieved.