[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