Commit fefc3728 authored by Nicolas Delaby's avatar Nicolas Delaby

* "get" method on CachePlugins should behave like a standard dictionary

 and return KeyError if not key found
* Raise KeyError when DistributedRamCache is not able to connect to memcached server
* call has_key before calling get on cache plugins.
* Update cache_plugin interface to explain expected behaviour


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@28000 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 7d7ccdf5
# -*- coding: utf-8 -*-
############################################################################## ##############################################################################
# #
# Copyright (c) 2004 Nexedi SARL and Contributors. All Rights Reserved. # Copyright (c) 2004 Nexedi SARL and Contributors. All Rights Reserved.
...@@ -88,15 +89,15 @@ class CacheFactory: ...@@ -88,15 +89,15 @@ class CacheFactory:
## Expired Cache (if needed) ## Expired Cache (if needed)
self.expire() self.expire()
if self.quick_cache.has_key(cache_id, scope):
quick_cached = self.quick_cache.get(cache_id, scope) quick_cached = self.quick_cache.get(cache_id, scope)
if quick_cached is not None: return quick_cached.getValue()
return quick_cached.value
else: else:
## not in local, check if it's in shared ## not in local, check if it's in shared
for shared_cache in self.shared_caches: for shared_cache in self.shared_caches:
if shared_cache.has_key(cache_id, scope): if shared_cache.has_key(cache_id, scope):
cache_entry = shared_cache.get(cache_id, scope) cache_entry = shared_cache.get(cache_id, scope)
value = cache_entry.value value = cache_entry.getValue()
## update local cache ## update local cache
self.quick_cache.set(cache_id, scope, value, self.quick_cache.set(cache_id, scope, value,
cache_duration, cache_duration,
......
...@@ -45,6 +45,8 @@ except ImportError: ...@@ -45,6 +45,8 @@ except ImportError:
## global ditionary containing connection objects ## global ditionary containing connection objects
connection_pool = {} connection_pool = {}
_MARKER = []
class DistributedRamCache(BaseCache): class DistributedRamCache(BaseCache):
""" Memcached based cache plugin. """ """ Memcached based cache plugin. """
...@@ -94,18 +96,24 @@ class DistributedRamCache(BaseCache): ...@@ -94,18 +96,24 @@ class DistributedRamCache(BaseCache):
return cache_id[:self._server_max_key_length] return cache_id[:self._server_max_key_length]
return cache_id return cache_id
def get(self, cache_id, scope, default=None): def get(self, cache_id, scope, default=_MARKER):
cache_storage = self.getCacheStorage() cache_storage = self.getCacheStorage()
cache_id = self.checkAndFixCacheId(cache_id, scope) cache_id = self.checkAndFixCacheId(cache_id, scope)
cache_entry = cache_storage.get(cache_id) cache_entry = cache_storage.get(cache_id)
if cache_entry is not None: #Simulate the behaviour of a standard Dictionary
# since some memcached-like products don't support expiration, we if not isinstance(cache_entry, CacheEntry):
if default is _MARKER:
#Error to connect memcached server
raise KeyError('Failed to retrieve value or to access memcached server: %s' % self._servers)
else:
return default
# since some memcached-like products does not support expiration, we
# check it by ourselves. # check it by ourselves.
if cache_entry.isExpired(): if cache_entry.isExpired():
cache_storage.delete(cache_id) cache_storage.delete(cache_id)
return default return default
self.markCacheHit() self.markCacheHit()
return cache_entry or default return cache_entry
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()
...@@ -131,7 +139,10 @@ class DistributedRamCache(BaseCache): ...@@ -131,7 +139,10 @@ class DistributedRamCache(BaseCache):
cache_storage.delete(cache_id) cache_storage.delete(cache_id)
def has_key(self, cache_id, scope): def has_key(self, cache_id, scope):
if self.get(cache_id, scope): cache_storage = self.getCacheStorage()
cache_id = self.checkAndFixCacheId(cache_id, scope)
cache_entry = cache_storage.get(cache_id)
if isinstance(cache_entry, CacheEntry):
return True return True
else: else:
return False return False
......
...@@ -72,23 +72,17 @@ class RamCache(BaseCache): ...@@ -72,23 +72,17 @@ class RamCache(BaseCache):
def get(self, cache_id, scope, default=None): def get(self, cache_id, scope, default=None):
cache = self.getCacheStorage() cache = self.getCacheStorage()
try: cache_entry = cache.get((scope, cache_id), default)
cache_entry = cache[(scope, cache_id)] cache_entry.markCacheHit()
# Note: tracking down cache hit could be achieved by uncommenting self.markCacheHit()
# methods below. In production environment this is likely uneeded
#cache_entry.markCacheHit()
#self.markCacheHit()
return cache_entry return cache_entry
except KeyError:
pass
return default
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 = self.getCacheStorage() cache = self.getCacheStorage()
cache[(scope, cache_id)] = CacheEntry(value, cache_duration, calculation_time) cache[(scope, cache_id)] = CacheEntry(value, cache_duration, calculation_time)
#self.markCacheMiss() self.markCacheMiss()
def expireOldCacheEntries(self, forceCheck = False): def expireOldCacheEntries(self, forceCheck=False):
now = time.time() now = time.time()
if forceCheck or (now > self._next_cache_expire_check_at): if forceCheck or (now > self._next_cache_expire_check_at):
## time to check for expired cache items ## time to check for expired cache items
......
...@@ -55,7 +55,9 @@ class ICachePlugin(Interface): ...@@ -55,7 +55,9 @@ class ICachePlugin(Interface):
""" """
def get(cache_id, scope, default=None): def get(cache_id, scope, default=None):
"""get the calculated value according to the cache_id and scope """get the calculated value according to the cache_id and scope.
raise KeyError if key does not exists and no default value provided.
return CacheEntry
""" """
def set(cache_id, scope, value, cache_duration=None, calculation_time=0): def set(cache_id, scope, value, cache_duration=None, calculation_time=0):
......
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