Commit 4a86ff7c authored by Aurel's avatar Aurel

display a warning message to let user know a cache factory is missing


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@13032 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent d1d7cf37
...@@ -30,7 +30,7 @@ import string ...@@ -30,7 +30,7 @@ import string
from time import time from time import time
from AccessControl.SecurityInfo import allow_class from AccessControl.SecurityInfo import allow_class
from CachePlugins.BaseCache import CachedMethodError from CachePlugins.BaseCache import CachedMethodError
from zLOG import LOG from zLOG import LOG, WARNING
DEFAULT_CACHE_SCOPE = 'GLOBAL' DEFAULT_CACHE_SCOPE = 'GLOBAL'
DEFAULT_CACHE_FACTORY = 'erp5_user_interface' DEFAULT_CACHE_FACTORY = 'erp5_user_interface'
...@@ -44,26 +44,26 @@ def initializePortalCachingProperties(self): ...@@ -44,26 +44,26 @@ def initializePortalCachingProperties(self):
is_cache_initialized = 1 is_cache_initialized = 1
## update cache structure from portal_caches ## update cache structure from portal_caches
self.getPortalObject().portal_caches.updateCache() self.getPortalObject().portal_caches.updateCache()
class CacheFactory: class CacheFactory:
""" CacheFactory is a RAM based object which contains different cache plugin """ CacheFactory is a RAM based object which contains different cache plugin
objects ordered in a list. objects ordered in a list.
""" """
cache_plugins = [] cache_plugins = []
cache_duration = 180 cache_duration = 180
def __init__(self, cache_plugins, cache_params): def __init__(self, cache_plugins, cache_params):
self.cache_plugins = cache_plugins self.cache_plugins = cache_plugins
self.cache_duration = cache_params.get('cache_duration') self.cache_duration = cache_params.get('cache_duration')
## separete local and shared cache plugins ## separete local and shared cache plugins
self.quick_cache = self.cache_plugins[0] self.quick_cache = self.cache_plugins[0]
try: try:
self.shared_caches =self.cache_plugins[1:] self.shared_caches =self.cache_plugins[1:]
except IndexError: except IndexError:
self.shared_caches = [] self.shared_caches = []
## set 'check_expire_cache_interval' to the minimal value between ## set 'check_expire_cache_interval' to the minimal value between
## individual 'check_expire_cache_interval' for each cache plugin contained ## individual 'check_expire_cache_interval' for each cache plugin contained
l = [] l = []
...@@ -72,13 +72,13 @@ class CacheFactory: ...@@ -72,13 +72,13 @@ class CacheFactory:
l.append(cp.cache_expire_check_interval) l.append(cp.cache_expire_check_interval)
l = filter(lambda x: x!=None and x!=0, l) l = filter(lambda x: x!=None and x!=0, l)
self.cache_expire_check_interval = min(l) self.cache_expire_check_interval = min(l)
def __call__(self, callable_object, cache_id, scope, cache_duration=None, *args, **kwd): def __call__(self, callable_object, cache_id, scope, cache_duration=None, *args, **kwd):
""" When CacheFactory is called it will try to return cached value using """ When CacheFactory is called it will try to return cached value using
appropriate cache plugin. appropriate cache plugin.
""" """
cache_duration = self.cache_duration cache_duration = self.cache_duration
## Expired Cache (if needed) ## Expired Cache (if needed)
self.expire() self.expire()
...@@ -96,14 +96,14 @@ class CacheFactory: ...@@ -96,14 +96,14 @@ class CacheFactory:
cache_entry.cache_duration, cache_entry.cache_duration,
cache_entry.calculation_time) cache_entry.calculation_time)
return value return value
## not in any available cache plugins calculate and set to local .. ## not in any available cache plugins calculate and set to local ..
start = time() start = time()
value = callable_object(*args, **kwd) value = callable_object(*args, **kwd)
end = time() end = time()
calculation_time = end - start calculation_time = end - start
self.quick_cache.set(cache_id, scope, value, cache_duration, calculation_time) self.quick_cache.set(cache_id, scope, value, cache_duration, calculation_time)
## .. and update rest of caches in chain except already updated local one ## .. and update rest of caches in chain except already updated local one
for shared_cache in self.shared_caches: for shared_cache in self.shared_caches:
shared_cache.set(cache_id, scope, value, cache_duration, calculation_time) shared_cache.set(cache_id, scope, value, cache_duration, calculation_time)
...@@ -116,15 +116,15 @@ class CacheFactory: ...@@ -116,15 +116,15 @@ class CacheFactory:
self._last_cache_expire_check_at = now self._last_cache_expire_check_at = now
for cache_plugin in self.getCachePluginList(): for cache_plugin in self.getCachePluginList():
cache_plugin.expireOldCacheEntries() cache_plugin.expireOldCacheEntries()
def getCachePluginList(self, omit_cache_plugin_name=None): def getCachePluginList(self, omit_cache_plugin_name=None):
""" get list of all cache plugins except specified by name in omit """ """ get list of all cache plugins except specified by name in omit """
rl = [] rl = []
for cp in self.cache_plugins: for cp in self.cache_plugins:
if omit_cache_plugin_name != cp.__class__.__name__: if omit_cache_plugin_name != cp.__class__.__name__:
rl.append(cp) rl.append(cp)
return rl return rl
def getCachePluginByClassName(self, cache_plugin_name): def getCachePluginByClassName(self, cache_plugin_name):
""" get cache plugin by its class name """ """ get cache plugin by its class name """
for cp in self.cache_plugins: for cp in self.cache_plugins:
...@@ -136,26 +136,26 @@ class CacheFactory: ...@@ -136,26 +136,26 @@ class CacheFactory:
""" clear cache for this cache factory """ """ clear cache for this cache factory """
for cp in self.cache_plugins: for cp in self.cache_plugins:
cp.clearCache() cp.clearCache()
class CachingMethod: class CachingMethod:
"""CachingMethod is a RAM based global Zope class which contains different """CachingMethod is a RAM based global Zope class which contains different
CacheFactory objects for every available ERP5 site instance. CacheFactory objects for every available ERP5 site instance.
""" """
## cache factories will be initialized for every ERP5 site ## cache factories will be initialized for every ERP5 site
factories = {} factories = {}
## replace string table for some control characters not allowed in cache id ## replace string table for some control characters not allowed in cache id
_cache_id_translate_table = string.maketrans("""[]()<>'", """,'__________') _cache_id_translate_table = string.maketrans("""[]()<>'", """,'__________')
def __init__(self, callable_object, id, cache_duration=180, def __init__(self, callable_object, id, cache_duration=180,
cache_factory=DEFAULT_CACHE_FACTORY): cache_factory=DEFAULT_CACHE_FACTORY):
"""Wrap a callable object in a caching method. """Wrap a callable object in a caching method.
callable_object must be callable. callable_object must be callable.
id is used to identify what call should be treated as the same call. id is used to identify what call should be treated as the same call.
cache_duration is an old argument kept for backwards compatibility. cache_duration is an old argument kept for backwards compatibility.
cache_duration is specified per cache factory. cache_duration is specified per cache factory.
cache_factory is the id of the cache_factory to use. cache_factory is the id of the cache_factory to use.
""" """
if not callable(callable_object): if not callable(callable_object):
...@@ -167,18 +167,18 @@ class CachingMethod: ...@@ -167,18 +167,18 @@ class CachingMethod:
self.callable_object = callable_object self.callable_object = callable_object
self.cache_duration = cache_duration self.cache_duration = cache_duration
self.cache_factory = cache_factory self.cache_factory = cache_factory
def __call__(self, *args, **kwd): def __call__(self, *args, **kwd):
"""Call the method or return cached value using appropriate cache plugin """ """Call the method or return cached value using appropriate cache plugin """
## cache scope is based on user which is a kwd argument ## cache scope is based on user which is a kwd argument
scope = kwd.get('scope', DEFAULT_CACHE_SCOPE) scope = kwd.get('scope', DEFAULT_CACHE_SCOPE)
## generate unique cache id ## generate unique cache id
cache_id = self.generateCacheId(self.id, *args, **kwd) cache_id = self.generateCacheId(self.id, *args, **kwd)
try: try:
## try to get value from cache in a try block ## try to get value from cache in a try block
## which is faster than checking for keys ## which is faster than checking for keys
# It is very important to take the factories dictionnary # It is very important to take the factories dictionnary
# on CachingMethod instead of self, we want a global variable # on CachingMethod instead of self, we want a global variable
...@@ -187,6 +187,7 @@ class CachingMethod: ...@@ -187,6 +187,7 @@ class CachingMethod:
*args, **kwd) *args, **kwd)
except KeyError: except KeyError:
## no caching enabled for this site or no such cache factory ## no caching enabled for this site or no such cache factory
LOG("Cache.__call__", WARNING, "Factory %s not found, method %s execute without cache" %(self.cache_factory, self.callable_object))
value = self.callable_object(*args, **kwd) value = self.callable_object(*args, **kwd)
return value return value
...@@ -200,8 +201,8 @@ class CachingMethod: ...@@ -200,8 +201,8 @@ class CachingMethod:
def generateCacheId(self, method_id, *args, **kwd): def generateCacheId(self, method_id, *args, **kwd):
""" Generate proper cache id based on *args and **kwd """ """ Generate proper cache id based on *args and **kwd """
## generate cache id out of arguments passed. ## generate cache id out of arguments passed.
## depending on arguments we may have different ## depending on arguments we may have different
## cache_id for same method_id ## cache_id for same method_id
cache_id = [method_id] cache_id = [method_id]
key_list = kwd.keys() key_list = kwd.keys()
key_list.sort() key_list.sort()
...@@ -214,7 +215,7 @@ class CachingMethod: ...@@ -214,7 +215,7 @@ class CachingMethod:
# sure to replace them # sure to replace them
cache_id = cache_id.translate(self._cache_id_translate_table) cache_id = cache_id.translate(self._cache_id_translate_table)
return cache_id return cache_id
allow_class(CachingMethod) allow_class(CachingMethod)
# TransactionCache is a cache per transaction. The purpose of this cache is # TransactionCache is a cache per transaction. The purpose of this cache is
...@@ -247,7 +248,7 @@ def clearCache(cache_factory_list=(DEFAULT_CACHE_FACTORY,)): ...@@ -247,7 +248,7 @@ def clearCache(cache_factory_list=(DEFAULT_CACHE_FACTORY,)):
"""Clear specified cache factory list.""" """Clear specified cache factory list."""
cache_storage = CachingMethod.factories cache_storage = CachingMethod.factories
for cf_key in cache_factory_list: for cf_key in cache_factory_list:
if cache_storage.has_key(cf_key): if cache_storage.has_key(cf_key):
for cp in cache_storage[cf_key].getCachePluginList(): for cp in cache_storage[cf_key].getCachePluginList():
cp.clearCache() cp.clearCache()
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