[Checkins] SVN: lovely.memcached/trunk/src/lovely/memcached/ implemented dependencies

Bernd Dorn bernd.dorn at lovelysystems.com
Mon Apr 16 13:14:06 EDT 2007


Log message for revision 74189:
  implemented dependencies

Changed:
  U   lovely.memcached/trunk/src/lovely/memcached/README.txt
  U   lovely.memcached/trunk/src/lovely/memcached/interfaces.py
  U   lovely.memcached/trunk/src/lovely/memcached/utility.py

-=-
Modified: lovely.memcached/trunk/src/lovely/memcached/README.txt
===================================================================
--- lovely.memcached/trunk/src/lovely/memcached/README.txt	2007-04-16 16:46:44 UTC (rev 74188)
+++ lovely.memcached/trunk/src/lovely/memcached/README.txt	2007-04-16 17:14:05 UTC (rev 74189)
@@ -197,6 +197,40 @@
   >>> util.query('a', raw=True) is None
   True
 
+Dependencies
+============
+
+It is possible to declare arbitrary python objects as so called
+dependencies upon setting a cache value. These dependencies can then
+be used to invalidate entries.
+
+  >>> util5 = MemcachedClient()
+  >>> k = util5.set('data1', 'key1', dependencies=['something'])
+  >>> k = util5.set('data2', 'key2', dependencies=['something'])
+
+  >>> util5.query('key1')
+  'data1'
+  >>> util5.query('key2')
+  'data2'
+  
+  >>> util.invalidate(dependencies=['otherthing'])
+  >>> util5.query('key1')
+  'data1'
+  >>> util5.query('key2')
+  'data2'
+  >>> util.invalidate(dependencies=['something', 'another thing'])
+  >>> util5.query('key1') is None
+  True
+  >>> util5.query('key2') is None
+  True
+  >>> k = util5.set('data3', 'key3', ns='1', dependencies=['something'])
+  >>> util.invalidate(dependencies=['something'])
+  >>> util5.query('key3', ns='1')
+  'data3'
+  >>> util.invalidate(ns='1', dependencies=['something'])
+  >>> util5.query('key3', ns='1') is None
+  True
+
 Statistics
 ==========
 

Modified: lovely.memcached/trunk/src/lovely/memcached/interfaces.py
===================================================================
--- lovely.memcached/trunk/src/lovely/memcached/interfaces.py	2007-04-16 16:46:44 UTC (rev 74188)
+++ lovely.memcached/trunk/src/lovely/memcached/interfaces.py	2007-04-16 17:14:05 UTC (rev 74189)
@@ -54,19 +54,35 @@
     def getStatistics():
         """returns the memcached stats"""
 
-    def set(data, key, lifetime=None, ns=None):
+    def set(data, key, lifetime=None, ns=None,
+            raw=False,
+            dependencies=[]):
         """Sets data with the given key in namespace. Lifetime
         defaults to defautlLifetime and ns defaults to the
-        default namespace"""
+        default namespace.
 
-    def query(key, default=None, ns=None):
+        The dependencies argument can be used to invalidate on
+        specific dependency markers.
+
+        This method returns the key that is generated by the utility.
+
+        If raw is True, the key is taken as is, and is not modified by
+        the utility, the key and the namespace need to be strings in
+        this case, otherwise a ValueError is raised.
+        """
+
+    def query(key, default=None, ns=None, raw=False):
         """query the cache for key in namespace, returns default if
         not found. ns defaults to default namespace."""
         
-    def invalidate(key, ns=None):
+    def invalidate(key=None, ns=None, raw=False, dependencies=[]):
         """invalidates key in namespace which defaults to default
-        namespace, currently we can not invalidate just a namespace"""
+        namespace, currently we can not invalidate just a namespace.
 
+        If dependencies are provided all, entries with such
+        dependencies are invalidated.
+        """
+
     def invalidateAll():
         """invalidates all data of the memcached servers, not that all
         namespaces are invalidated"""

Modified: lovely.memcached/trunk/src/lovely/memcached/utility.py
===================================================================
--- lovely.memcached/trunk/src/lovely/memcached/utility.py	2007-04-16 16:46:44 UTC (rev 74188)
+++ lovely.memcached/trunk/src/lovely/memcached/utility.py	2007-04-16 17:14:05 UTC (rev 74189)
@@ -38,6 +38,8 @@
 NS = 'lovely.memcached'
 # namespace for key timesamps
 STAMP_NS = NS + '.stamps'
+# namespace for deps
+DEP_NS = NS + '.dep'
 
 class MemcachedClient(persistent.Persistent):
     interface.implements(IMemcachedClient)
@@ -62,7 +64,8 @@
     def getStatistics(self):
         return self.client.get_stats()
 
-    def set(self, data, key, lifetime=None, ns=None, raw=False):
+    def set(self, data, key, lifetime=None, ns=None, raw=False,
+            dependencies=[]):
         if lifetime is None:
             lifetime = self.defaultLifetime
         ns = ns or self.defaultNS or None
@@ -75,7 +78,18 @@
         bKey = self._buildKey(key, ns, raw=raw)
         self.client.set(bKey, data, lifetime)
         self._keysSet(key, ns, lifetime)
+        self._depSet(bKey, ns, dependencies)
         return bKey
+
+    def _depSet(self, key, ns, deps):
+        for dep in deps:
+            depKey = self._buildDepKey(dep, ns)
+            keys = self.client.get(depKey)
+            if keys is None:
+                keys = (key,)
+            else:
+                keys = keys +  (key,)
+            self.client.set(depKey, keys)
         
     def query(self, key, default=None, ns=None, raw=False):
         ns = ns or self.defaultNS or None
@@ -84,12 +98,22 @@
             return default
         return cPickle.loads(res)
 
-    def invalidate(self, key, ns=None, raw=False):
+    def _buildDepKey(self, dep, ns):
+        return DEP_NS + self._buildKey(dep, ns)
+
+    def invalidate(self, key=None, ns=None, raw=False, dependencies=[]):
         ns = ns or self.defaultNS or None
         log.debug('invalidate: %r, %r '% (key, ns))
         if self.trackKeys:
             self.client.delete(self._buildKey((ns, key), STAMP_NS))
         self.client.delete(self._buildKey(key, ns, raw))
+        for dep in dependencies:
+            depKey = self._buildDepKey(dep, ns)
+            keys = self.client.get(depKey)
+            self.invalidate(depKey)
+            if keys is not None:
+                for key in keys:
+                    self.client.delete(key)
 
     def invalidateAll(self):
         # notice this does not look at namespaces



More information about the Checkins mailing list