From 3088f3860de1019838f362ba3f296dabde9d23bc Mon Sep 17 00:00:00 2001
From: Nicolas Delaby <nicolas@nexedi.com>
Date: Mon, 18 May 2009 08:47:33 +0000
Subject: [PATCH] CachePlugins impliment ICachePlugin Interface

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@27013 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 .../CachePlugins/DistributedRamCache.py       | 43 +++++++++++--------
 product/ERP5Type/CachePlugins/RamCache.py     | 19 +++++---
 product/ERP5Type/CachePlugins/SQLCache.py     | 14 ++++--
 product/ERP5Type/CachePlugins/ZODBCache.py    |  8 +++-
 4 files changed, 56 insertions(+), 28 deletions(-)

diff --git a/product/ERP5Type/CachePlugins/DistributedRamCache.py b/product/ERP5Type/CachePlugins/DistributedRamCache.py
index 5b96e7f9b3..cc9606d996 100644
--- a/product/ERP5Type/CachePlugins/DistributedRamCache.py
+++ b/product/ERP5Type/CachePlugins/DistributedRamCache.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 # Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
@@ -33,6 +34,8 @@ from thread import get_ident
 from zLOG import LOG
 from BaseCache import BaseCache
 from BaseCache import CacheEntry
+from Products.ERP5Type import Interface
+import zope.interface
 
 try:
   import memcache
@@ -42,28 +45,32 @@ except ImportError:
 
 ## global ditionary containing connection objects
 connection_pool = {}
- 
+
 class DistributedRamCache(BaseCache):
   """ Memcached based cache plugin. """
 
-  def __init__(self, params):
+  zope.interface.implements(
+        Interface.ICachePlugin
+    )
+
+  def __init__(self, params={}):
     self._servers = params.get('server', '')
     self._debugLevel = params.get('debugLevel', 0)
     BaseCache.__init__(self)
-    
+
   def initCacheStorage(self):
     """ Init cache storage """
     ## cache storage is a memcached server and no need to init it
     pass
-        
-  def getCacheStorage(self):
+
+  def getCacheStorage(self, **kw):
     ## if we use one connection object this causes 
     ## "MemCached: while expecting 'STORED', got unexpected response 'END'"
     ## messages in log files and can sometimes can block the thread. 
     ## For the moment we create a new conn object for every thread.
     global connection_pool
     thread_id = get_ident()
-    
+
     memcache_conn = connection_pool.get(thread_id, None)
     if memcache_conn is None:
       ## we don't have memcache_conn for this thread
@@ -73,21 +80,21 @@ class DistributedRamCache(BaseCache):
     else:
       ## we have memcache_conn for this thread
       return memcache_conn
-       
+
   def checkAndFixCacheId(self, cache_id, scope):
     ## memcached doesn't support namespaces (cache scopes) so to "emmulate"
     ## such behaviour when constructing cache_id we add scope in front
     cache_id = "%s.%s" %(scope, cache_id) 
     ## memcached will fail to store cache_id longer than MEMCACHED_SERVER_MAX_KEY_LENGTH.
     return cache_id[:MEMCACHED_SERVER_MAX_KEY_LENGTH]
-    
+
   def get(self, cache_id, scope, default=None):
     cache_storage = self.getCacheStorage()
     cache_id = self.checkAndFixCacheId(cache_id, scope)
     cache_entry = cache_storage.get(cache_id)
-    #self.markCacheHit()
+    self.markCacheHit()
     return cache_entry
-       
+
   def set(self, cache_id, scope, value, cache_duration= None, calculation_time=0):
     cache_storage = self.getCacheStorage()
     cache_id = self.checkAndFixCacheId(cache_id, scope)
@@ -97,8 +104,8 @@ class DistributedRamCache(BaseCache):
       cache_duration = 86400
     cache_entry = CacheEntry(value, cache_duration, calculation_time)
     cache_storage.set(cache_id, cache_entry, cache_duration)
-    #self.markCacheMiss()
-   
+    self.markCacheMiss()
+
   def expireOldCacheEntries(self, forceCheck = False):
     """ Memcache has its own built in expire policy """
     ## we can not use one connection to memcached server for time being of DistributedRamCache
@@ -108,13 +115,13 @@ class DistributedRamCache(BaseCache):
     ## but that's too much overhead or create a new connection when cache is to be expired. 
     ## This way we can catch memcached server failures. BTW: This hack is forced by the lack functionality in python-memcached 
     #self._cache = memcache.Client(self._servers.split('\n'), debug=self._debugLevel) 
-    pass    
-        
+    pass
+
   def delete(self, cache_id, scope):
     cache_storage = self.getCacheStorage()
     cache_id = self.checkAndFixCacheId(cache_id, scope)
     cache_storage.delete(cache_id)
-        
+
   def has_key(self, cache_id, scope):
     if self.get(cache_id, scope):
       return True
@@ -124,7 +131,7 @@ class DistributedRamCache(BaseCache):
   def getScopeList(self):
     ## memcached doesn't support namespaces (cache scopes) neither getting cached key list 
     return []
-    
+
   def getScopeKeyList(self, scope):
     ## memcached doesn't support namespaces (cache scopes) neither getting cached key list 
     return []
@@ -133,12 +140,12 @@ class DistributedRamCache(BaseCache):
     BaseCache.clearCache(self)
     cache_storage = self.getCacheStorage()
     cache_storage.flush_all()
-    
+
   def clearCacheForScope(self, scope):
     ## memcached doesn't support namespaces (cache scopes) neither getting cached key list.
     ## Becasue we've explicitly called this function instead of clearing specific cache 
     ## scope we have no choice but clear whole cache.
-    self.clearCache()       
+    self.clearCache()
 
   def getCachePluginTotalMemorySize(self):
     """ Calculate total RAM memory size of cache plugin. """
diff --git a/product/ERP5Type/CachePlugins/RamCache.py b/product/ERP5Type/CachePlugins/RamCache.py
index 32a6e09825..a1185368e7 100644
--- a/product/ERP5Type/CachePlugins/RamCache.py
+++ b/product/ERP5Type/CachePlugins/RamCache.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 # Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
@@ -32,6 +33,8 @@ Local RAM based cache plugin.
 
 import time
 from BaseCache import BaseCache, CacheEntry
+from Products.ERP5Type import Interface
+import zope.interface
 
 def calcPythonObjectMemorySize(i):
   """ Recursive function that will 'walk' over complex python types and caclulate
@@ -48,7 +51,11 @@ def calcPythonObjectMemorySize(i):
 
 class RamCache(BaseCache):
   """ RAM based cache plugin."""
-   
+
+  zope.interface.implements(
+        Interface.ICachePlugin
+    )
+
   _cache_dict = {}
   cache_expire_check_interval = 300
     
@@ -60,7 +67,7 @@ class RamCache(BaseCache):
     ## cache storage is a RAM based dictionary
     pass
     
-  def getCacheStorage(self):
+  def getCacheStorage(self, **kw):
     return self._cache_dict
     
   def get(self, cache_id, scope, default=None):
@@ -110,18 +117,18 @@ class RamCache(BaseCache):
     for scope, cache_id in self.getCacheStorage().iterkeys():
       scope_set.add(scope)
     return list(scope_set)
-    
+
   def getScopeKeyList(self, scope):
     key_list = []
     for key in self.getCacheStorage().iterkeys():
       if scope == key[0]:
         key_list.append(key[1])
     return key_list
-    
+
   def clearCache(self):
     BaseCache.clearCache(self)
     self.getCacheStorage().clear()
-    
+
   def clearCacheForScope(self, scope):
     cache = self.getCacheStorage()
     for key in cache.keys():
@@ -131,7 +138,7 @@ class RamCache(BaseCache):
         except KeyError:
           # The key might have disappeared, due to multi-threading.
           pass
-      
+
   def getCachePluginTotalMemorySize(self):
     """ Calculate total RAM memory size of cache plugin. 
         This function depends on mxBase python module:
diff --git a/product/ERP5Type/CachePlugins/SQLCache.py b/product/ERP5Type/CachePlugins/SQLCache.py
index b7723cae19..66562b7af0 100644
--- a/product/ERP5Type/CachePlugins/SQLCache.py
+++ b/product/ERP5Type/CachePlugins/SQLCache.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 ##############################################################################
 #
 # Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
@@ -35,6 +36,8 @@ import time
 import base64
 from zLOG import LOG
 from BaseCache import BaseCache, CacheEntry, CachedMethodError
+from Products.ERP5Type import Interface
+import zope.interface
 
 try:
   import cPickle as pickle
@@ -58,7 +61,11 @@ connection_pool = {}
   
 class SQLCache(BaseCache):
   """ SQL based cache plugin. """
-    
+
+  zope.interface.implements(
+        Interface.ICachePlugin
+    )
+
   cache_expire_check_interval = 3600
     
   create_table_sql = '''CREATE TABLE %s(cache_id VARBINARY(970) NOT NULL, 
@@ -115,7 +122,7 @@ class SQLCache(BaseCache):
                             
   find_table_by_name_sql = """SHOW TABLES LIKE '%s' """
   
-  def __init__(self, params):
+  def __init__(self, params={}):
     BaseCache.__init__(self)
     self._dbConn = None
     self._db_server = params.get('server', '')
@@ -139,12 +146,13 @@ class SQLCache(BaseCache):
       ## no such table create it
       self.execSQLQuery(self.create_table_sql %self._db_cache_table_name) 
   
-  def getCacheStorage(self, force_reconnect=False):
+  def getCacheStorage(self, **kw):
     """ 
     Return current DB connection or create a new one for this thread.
     See http://sourceforge.net/docman/display_doc.php?docid=32071&group_id=22307
     especially threadsafety part why we create for every thread a new MySQL db connection object.
     """
+    force_reconnect = kw.get('force_reconnect', False)
     global connection_pool
     thread_id = get_ident()
     
diff --git a/product/ERP5Type/CachePlugins/ZODBCache.py b/product/ERP5Type/CachePlugins/ZODBCache.py
index fc41b4f16a..18c9a93e48 100644
--- a/product/ERP5Type/CachePlugins/ZODBCache.py
+++ b/product/ERP5Type/CachePlugins/ZODBCache.py
@@ -33,12 +33,18 @@ ZODB Based cache plugin.
 import time
 from BaseCache import BaseCache, CacheEntry
 from BTrees.OOBTree import OOBTree
+from Products.ERP5Type import Interface
+import zope.interface
 
 PRIVATE_ATTRIBUTE_ZODB_CACHE_NAME = '_zodb_cache'
 
 class ZODBCache(BaseCache):
   """ ZODB based cache plugin."""
 
+  zope.interface.implements(
+        Interface.ICachePlugin
+    )
+
   cache_tool = None
   cache_expire_check_interval = 300
 
@@ -55,7 +61,7 @@ class ZODBCache(BaseCache):
     if getattr(self.cache_tool, PRIVATE_ATTRIBUTE_ZODB_CACHE_NAME, None) is None:
       self.cache_tool._zodb_cache = OOBTree()
 
-  def getCacheStorage(self):
+  def getCacheStorage(self, **kw):
     return getattr(self.cache_tool, PRIVATE_ATTRIBUTE_ZODB_CACHE_NAME)
 
   def get(self, cache_id, scope, default=None):
-- 
2.30.9