Commit 5f2d7bb8 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

implement clearCache() in DistributeRamCache by using different keys in low-level.

parent 4c76bc61
...@@ -56,6 +56,7 @@ class DistributedRamCache(BaseCache): ...@@ -56,6 +56,7 @@ class DistributedRamCache(BaseCache):
) )
def __init__(self, uid, params={}): def __init__(self, uid, params={}):
self._uid = uid
self._servers = params.get('server', '') self._servers = params.get('server', '')
self._expiration_time = params.get('expiration_time', 0) self._expiration_time = params.get('expiration_time', 0)
self._server_max_key_length = params.get('server_max_key_length', 250) self._server_max_key_length = params.get('server_max_key_length', 250)
...@@ -93,14 +94,15 @@ class DistributedRamCache(BaseCache): ...@@ -93,14 +94,15 @@ class DistributedRamCache(BaseCache):
def getCacheStorage(self, **kw): def getCacheStorage(self, **kw):
"""Follow MemcachedTool.getMemcachedDict implementation """Follow MemcachedTool.getMemcachedDict implementation
""" """
return SharedDict(self._getMemcachedDict(), prefix=self._key_prefix) return SharedDict(self._getMemcachedDict(), prefix=self._key_prefix, uid=self._uid)
def _getCacheId(self, cache_id, scope): def _getCacheId(self, cache_id, scope):
return '%s_%s' % (scope, cache_id) return '%s_%s' % (scope, cache_id)
def get(self, cache_id, scope, default=_MARKER): def get(self, cache_id, scope, default=_MARKER):
cache_storage = self.getCacheStorage() cache_storage = self.getCacheStorage()
cache_id = self._getCacheId(cache_id, scope) revision = cache_storage.getRevision()
cache_id = '%s:%s' % (revision, self._getCacheId(cache_id, scope))
cache_entry = cache_storage.get(cache_id) cache_entry = cache_storage.get(cache_id)
if isinstance(cache_entry, CacheEntry): if isinstance(cache_entry, CacheEntry):
# since some memcached-like products does not support expiration, we # since some memcached-like products does not support expiration, we
...@@ -117,7 +119,8 @@ class DistributedRamCache(BaseCache): ...@@ -117,7 +119,8 @@ class DistributedRamCache(BaseCache):
def set(self, cache_id, scope, value, cache_duration=None, calculation_time=0): def set(self, cache_id, scope, value, cache_duration=None, calculation_time=0):
cache_storage = self.getCacheStorage() cache_storage = self.getCacheStorage()
cache_id = self._getCacheId(cache_id, scope) revision = cache_storage.getRevision()
cache_id = '%s:%s' % (revision, self._getCacheId(cache_id, scope))
cache_entry = CacheEntry(value, cache_duration, calculation_time) cache_entry = CacheEntry(value, cache_duration, calculation_time)
cache_storage.set(cache_id, cache_entry) cache_storage.set(cache_id, cache_entry)
self.markCacheMiss() self.markCacheMiss()
...@@ -135,12 +138,14 @@ class DistributedRamCache(BaseCache): ...@@ -135,12 +138,14 @@ class DistributedRamCache(BaseCache):
def delete(self, cache_id, scope): def delete(self, cache_id, scope):
cache_storage = self.getCacheStorage() cache_storage = self.getCacheStorage()
cache_id = self._getCacheId(cache_id, scope) revision = cache_storage.getRevision()
cache_id = '%s:%s' % (revision, self._getCacheId(cache_id, scope))
del cache_storage[cache_id] del cache_storage[cache_id]
def has_key(self, cache_id, scope): def has_key(self, cache_id, scope):
cache_storage = self.getCacheStorage() cache_storage = self.getCacheStorage()
cache_id = self._getCacheId(cache_id, scope) revision = cache_storage.getRevision()
cache_id = '%s:%s' % (revision, self._getCacheId(cache_id, scope))
cache_entry = cache_storage.get(cache_id) cache_entry = cache_storage.get(cache_id)
to_return = False to_return = False
if isinstance(cache_entry, CacheEntry): if isinstance(cache_entry, CacheEntry):
...@@ -164,7 +169,7 @@ class DistributedRamCache(BaseCache): ...@@ -164,7 +169,7 @@ class DistributedRamCache(BaseCache):
Use expiration time instead. Use expiration time instead.
""" """
BaseCache.clearCache(self) BaseCache.clearCache(self)
LOG('DistributedRamCache', WARNING, 'not allowed to clear memcache storage') self.getCacheStorage().increaseRevision()
def clearCacheForScope(self, scope): def clearCacheForScope(self, scope):
## memcached doesn't support namespaces (cache scopes) neither getting cached key list. ## memcached doesn't support namespaces (cache scopes) neither getting cached key list.
......
...@@ -136,9 +136,14 @@ if memcache is not None: ...@@ -136,9 +136,14 @@ if memcache is not None:
for key, action in self.scheduled_action_dict.iteritems(): for key, action in self.scheduled_action_dict.iteritems():
encoded_key = encodeKey(key) encoded_key = encodeKey(key)
if action is UPDATE_ACTION: if action is UPDATE_ACTION:
succeed = self.memcached_connection.set(encoded_key, if key.endswith('/_revision'):
self.local_cache[key], # We want to keep the revision value as long as possible.
expiration_time) succeed = self.memcached_connection.set(encoded_key,
self.local_cache[key])
else:
succeed = self.memcached_connection.set(encoded_key,
self.local_cache[key],
expiration_time)
if not succeed: if not succeed:
self._initialiseConnection() self._initialiseConnection()
succeed = self.memcached_connection.set(encoded_key, succeed = self.memcached_connection.set(encoded_key,
...@@ -226,15 +231,18 @@ if memcache is not None: ...@@ -226,15 +231,18 @@ if memcache is not None:
Each "user" of the dictionary must get an instance of this class. Each "user" of the dictionary must get an instance of this class.
""" """
def __init__(self, dictionary, prefix): def __init__(self, dictionary, prefix, uid=None):
""" """
dictionary dictionary
Instance of dictionary to share. Instance of dictionary to share.
prefix prefix
Prefix used by the "user" owning an instance of this class. Prefix used by the "user" owning an instance of this class.
uid
Unique ID for the different scope of the revision.
""" """
self._dictionary = dictionary self._dictionary = dictionary
self.prefix = prefix self.prefix = prefix
self._uid = uid
def _prefixKey(self, key): def _prefixKey(self, key):
if not isinstance(key, basestring): if not isinstance(key, basestring):
...@@ -261,6 +269,16 @@ if memcache is not None: ...@@ -261,6 +269,16 @@ if memcache is not None:
def set(self, key, value): def set(self, key, value):
self._dictionary.set(self._prefixKey(key), value) self._dictionary.set(self._prefixKey(key), value)
def getRevision(self):
revision = self.get('%s/_revision' % self._uid, None)
if revision is None:
revision = time.time()
self.set('%s/_revision' % self._uid, revision)
return revision
def increaseRevision(self):
self.set('%s/_revision' % self._uid, time.time())
allow_class(SharedDict) allow_class(SharedDict)
class MemcachedTool(_MemcacheTool): class MemcachedTool(_MemcacheTool):
...@@ -291,7 +309,7 @@ if memcache is not None: ...@@ -291,7 +309,7 @@ if memcache is not None:
global_prefix = self.erp5_site_global_id global_prefix = self.erp5_site_global_id
if global_prefix: if global_prefix:
key_prefix = global_prefix + '_' + key_prefix key_prefix = global_prefix + '_' + key_prefix
return SharedDict(memcached_plugin.getConnection(), prefix=key_prefix) return SharedDict(memcached_plugin.getConnection(), prefix=key_prefix, uid=plugin_path)
InitializeClass(MemcachedTool) InitializeClass(MemcachedTool)
else: else:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment