Commit ec07222e authored by Ivan Tyagov's avatar Ivan Tyagov

Distributed and SQL Cache plugins use pool of connections per thread basis.

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@11143 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 0051e2fd
......@@ -33,15 +33,16 @@ Memcached based cache plugin.
from BaseCache import *
from time import time
from zLOG import LOG
from thread import get_ident
try:
import memcache
MEMCACHED_SERVER_MAX_KEY_LENGTH = memcache.SERVER_MAX_KEY_LENGTH
except ImportError:
LOG('DistributedRamCache',0,'unable to import memcache')
LOG('DistributedRamCache', 0, 'unable to import memcache')
## number of seconds before creating a new connection to memcached server
##KEEP_ALIVE_MEMCACHED_CONNECTION_INTERVAL = 30
## global ditionary containing connection objects
connection_pool = {}
class DistributedRamCache(BaseCache):
""" Memcached based cache plugin. """
......@@ -53,30 +54,23 @@ class DistributedRamCache(BaseCache):
BaseCache.__init__(self)
def getCacheStorage(self):
## if we use one connection object this causes "MemCached: while expecting 'STORED', got unexpected response 'END'"
## messages in log files and thus sometimes can block the thread. For the moment we create
## a new conn object for every memcache access which in turns means another socket.
## See addiionaly expireOldCacheEntries() comments for one or many connections.
try:
from Products.ERP5Type.Utils import get_request
request = get_request()
except ImportError:
request = None
if request is not None:
## Zope/ERP5 environment
memcache_conn = request.get('_erp5_memcache_connection', None)
if not memcache_conn:
## we have not memcache_conn for this request
memcache_conn = memcache.Client(self._servers.split('\n'), debug=self._debugLevel)
request.set('_erp5_memcache_connection', memcache_conn)
return memcache_conn
else:
## we have memcache_conn for this request
return memcache_conn
## 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
memcache_conn = memcache.Client(self._servers.split('\n'), debug=self._debugLevel)
connection_pool[thread_id] = memcache_conn
return memcache_conn
else:
## run from unit tests
return memcache.Client(self._servers.split('\n'), debug=self._debugLevel)
## 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"
......
......@@ -32,6 +32,8 @@ SQL (MySQL) based cache plugin.
from BaseCache import *
import time, base64
from zLOG import LOG
from thread import get_ident
try:
import cPickle as pickle
......@@ -41,8 +43,12 @@ except ImportError:
try:
import MySQLdb
except ImportError:
raise CachedMethodError, "MySQLdb module is not available"
LOG('SQLCache', 0, 'unable to import MySQLdb')
## global ditionary containing connection objects
connection_pool = {}
class SQLCache(BaseCache):
""" SQL based cache plugin. """
......@@ -114,37 +120,26 @@ class SQLCache(BaseCache):
def getCacheStorage(self):
"""
Return current DB connection or create a new one for his thread.
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 every time a new MySQL db connection object.
especially threadsafety part why we create for every thread a new MySQL db connection object.
"""
try:
from Products.ERP5Type.Utils import get_request
request = get_request()
except ImportError:
request = None
if request is not None:
## Zope/ERP5 environment
dbConn = request.get('_erp5_dbcache_connection', None)
if not dbConn:
## we have not dbConn for this request
dbConn = MySQLdb.connect(host=self._db_server, \
user=self._db_user,\
passwd=self._db_passwd, \
db=self._db_name)
request.set('_erp5_dbcache_connection', dbConn)
return dbConn
else:
## we have already dbConn for this request
return dbConn
else:
## run from unit tests
global connection_pool
thread_id = get_ident()
dbConn = connection_pool.get(thread_id, None)
if dbConn is None:
## we don't have dbConn for this thread
dbConn = MySQLdb.connect(host=self._db_server, \
user=self._db_user,\
passwd=self._db_passwd, \
db=self._db_name)
user=self._db_user,\
passwd=self._db_passwd, \
db=self._db_name)
connection_pool[thread_id] = dbConn
return dbConn
else:
## we have already dbConn for this thread
return dbConn
def get(self, cache_id, scope, default=None):
sql_query = self.get_key_sql %(self._db_cache_table_name, cache_id, scope)
......
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