Anonymous avatar Anonymous committed 0ee7467

- doc fixes, simplify serialization
- think about key mangling and cache versions

Comments (0)

Files changed (4)

     (payload, metadata)
 
 Where "payload" is the thing being cached, and "metadata" is information
-we store in the cache regarding the created time, expiration time.  The
-tuple can be pickled assuming the payload is pickleable, or to get a serialized
-version of just the metadata, you can call the ``serialized_metadata`` accessor,
-which is then turned back into a ``CachedValue`` via the ``deserialize``
-method::
-
-    from dogpile.cache.backend import CachedValue
-
-    def get(self, key):
-        my_cached_value = my_cache.get(key)
-        serialized_metadata, payload = my_cached_value.split("|")
-        return CachedValue.deserialize(payload, serialized_metadata)
-
-    def put(self, key, value):
-        my_value_to_cache = value.serialized_metadata + "|" + repr(value.payload)
-        my_cache.put(key, my_value_to_cache)
-
+we store in the cache - a dictionary which currently has just the "creation time"
+and a "version identifier" as key/values.  If the cache backend requires serialization, 
+pickle or similar can be used on the tuple - the "metadata" portion will always
+be a small and easily serializable Python structure.
 
 Region Arguments
 ----------------

dogpile/cache/api.py

 class CacheBackend(object):
     """Base class for backend implementations."""
 
+    key_mangler = None
+    """Key mangling function.  
+    
+    May be None.
+    """
+
     def __init__(self, arguments):
         """Construct a new :class:`.CacheBackend`.
         

dogpile/cache/region.py

-
+from dogpile import Dogpile, NeedRegenerationException
 from dogpile.cache.util import function_key_generator, PluginLoader
+from dogpile.cache.api import NO_VALUE, CachedValue
+import time
 
 _backend_loader = PluginLoader("dogpile.cache")
 register_backend = _backend_loader.register
 import backends
 
+value_version = 1
+"""An integer placed in the :class:`.CachedValue`
+so that new versions of dogpile.cache can detect cached
+values from a previous, backwards-incompatible version.
+
+"""
 
 class CacheRegion(object):
     """A front end to a particular cache backend."""
     def __init__(self, name, 
             expiration_time=None,
             arguments=None,
-            function_key_generator=function_key_generator
+            function_key_generator=function_key_generator,
             key_mangler=None,
         ):
         """Construct a new :class:`.CacheRegion`.
         :function_key_generator: Key generator used by
          :meth:`.CacheRegion.cache_on_arguments`.
         :key_mangler: Function which will be used on all incoming
-         keys before passing to the backend.  Defaults to ``None``.
-         A simple key mangler is the SHA1 mangler function
-         found at :meth:`.sha1_mangle_key`.
+         keys before passing to the backend.  Defaults to ``None``,
+         in which case the key mangling function recommended by
+         the cache backend will be used.    A typical mangler
+         is the SHA1 mangler found at found at :meth:`.sha1_mangle_key` 
+         which coerces keys into a SHA1
+         hash, so that the string length is fixed.  To
+         disable all key mangling, set to ``False``.
          
         """
         self.backend = _backend_loader.load(name)(arguments)
         self.function_key_generator = function_key_generator
-        self.key_mangler = key_mangler
+        if key_mangler:
+            self.key_mangler = key_mangler
+        elif key_mangler is False:
+            self.key_mangler = None
+        else:
+            self.key_mangler = backend.key_mangler
         self.dogpile_registry = Dogpile.registry(expiration_time)
 
     def get(self, key):
 
         def get_value():
             value = self.backend.get(key)
-            if value is NO_VALUE:
+            if value is NO_VALUE or \
+                value.metadata['version'] != value_version:
                 raise NeedRegenerationException()
             return value.payload, value.metadata["creation_time"]
 
         def gen_value():
-            value = CachedValue(creator(), {"creation_time":time.time()})
+            value = CachedValue(
+                        creator(), 
+                        {
+                            "creation_time":time.time(), 
+                            "version":value_version
+                        })
             self.backend.put(key, value)
             return value
 

dogpile/cache/util.py

                 self.impls[name] = impl.load
                 return impl.load()
             else:
-                raise exceptions.RuntimeException(
+                raise Exception(
                         "Can't load plugin %s %s" % 
                         (self.group, name))
 
     if kls:
         namespace = '%s.%s' % (kls.__module__, kls.__name__)
     else:
-        namespace = '%s|%s' % (inspect.getsourcefile(func), func.__name__)
+        namespace = '%s|%s' % (inspect.getsourcefile(fn), fn.__name__)
 
-    args = inspect.getargspec(func)
+    args = inspect.getargspec(fn)
     has_self = args[0] and args[0][0] in ('self', 'cls')
     def generate_key(*args, **kw):
         if kw:
                     "function does not accept keyword arguments.")
         if has_self:
             args = args[1:]
-        return  " ".join(map(unicode, deco_args + args))
+        return namespace + "|" + " ".join(map(unicode, args))
     return generate_key
 
 def sha1_mangle_key(key):
     """a SHA1 key mangler."""
 
     return sha1(key).hexdigest()
+
+def length_conditional_mangler(length, mangler):
+    """a key mangler that mangles if the length of the key is
+    past a certain threshold.
+    
+    """
+    def mangle(key):
+        if len(key) >= length:
+            return mangler(key)
+        else:
+            return key
+    return mangle
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.