Commit 8676b850 authored by Vincent Pelletier's avatar Vincent Pelletier

Drop unneeded use of thread-local.

memcache module already handle thread-safety, and we actually want to be
transaction-local here, so use a volatile variable instead for caching
needs.
Removes the need to restart Zope for connection parameter changes to take
effect.
Fixes a bad interaction with SelectionTool's code, which causes
transactional isolation to be broken (just for this connector) and too many
network connections to be used.
parent 2e874eb7
...@@ -31,7 +31,8 @@ from AccessControl import ClassSecurityInfo ...@@ -31,7 +31,8 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type import PropertySheet from Products.ERP5Type import PropertySheet
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Tool.MemcachedTool import memcached_dict_pool from Products.ERP5Type.Tool.MemcachedTool import MemcachedDict
from Products.ERP5Type.Globals import InitializeClass
class MemcachedPlugin(XMLObject): class MemcachedPlugin(XMLObject):
"""Memcached Plugin authorise Memcached Tool to connect several backends. """Memcached Plugin authorise Memcached Tool to connect several backends.
...@@ -57,16 +58,25 @@ class MemcachedPlugin(XMLObject): ...@@ -57,16 +58,25 @@ class MemcachedPlugin(XMLObject):
, PropertySheet.Url , PropertySheet.Url
) )
def manage_beforeDelete(self, *args, **kw): security.declarePublic('getConnection')
def getConnection(self):
try: try:
del(memcached_dict_pool.memcached_dict) key, connection = self._v_connection
except AttributeError: except AttributeError:
pass key = None
XMLObject.manage_beforeDelete(self, *args, **kw) url = self.getUrlString()
expiration = self.getExpirationTime()
max_key_length = self.getServerMaxKeyLength()
max_value_length = self.getServerMaxValueLength()
my_key = (url, expiration, max_key_length, max_value_length)
if key != my_key:
connection = MemcachedDict(
(url, ),
expiration_time=expiration,
server_max_key_length=max_key_length,
server_max_value_length=max_value_length,
)
self._v_connection = my_key, connection
return connection
def manage_afterAdd(self, *args, **kw): InitializeClass(MemcachedPlugin)
try:
del(memcached_dict_pool.memcached_dict)
except AttributeError:
pass
XMLObject.manage_afterAdd(self, *args, **kw)
...@@ -26,8 +26,6 @@ ...@@ -26,8 +26,6 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
############################################################################## ##############################################################################
from threading import local
from Products.ERP5Type.Tool.BaseTool import BaseTool from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type import Permissions, _dtmldir from Products.ERP5Type import Permissions, _dtmldir
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
...@@ -59,7 +57,6 @@ def encodeKey(key): ...@@ -59,7 +57,6 @@ def encodeKey(key):
# control characters and white spaces. # control characters and white spaces.
return encodestring(key, True).replace('\n', '').replace('\r', '') return encodestring(key, True).replace('\n', '').replace('\r', '')
memcached_dict_pool = local()
if memcache is not None: if memcache is not None:
# Real memcache tool # Real memcache tool
from Shared.DC.ZRDB.TM import TM from Shared.DC.ZRDB.TM import TM
...@@ -267,28 +264,6 @@ if memcache is not None: ...@@ -267,28 +264,6 @@ if memcache is not None:
memcached_tool_configure = DTMLFile('memcached_tool_configure', _dtmldir) memcached_tool_configure = DTMLFile('memcached_tool_configure', _dtmldir)
erp5_site_global_id = '' erp5_site_global_id = ''
def _getMemcachedDict(self, plugin_path):
"""
Return used memcached dict.
Create it if does not exist.
"""
try:
local_dict = memcached_dict_pool.local_dict
except AttributeError:
local_dict = memcached_dict_pool.local_dict = {}
try:
dictionary = local_dict[plugin_path]
except KeyError:
memcached_plugin = self.restrictedTraverse(plugin_path, None)
if memcached_plugin is None:
raise ValueError, 'Memcached Plugin does not exists: %r' % (plugin_path,)
dictionary = MemcachedDict((memcached_plugin.getUrlString(''),),
expiration_time=memcached_plugin.getExpirationTime(),
server_max_key_length=memcached_plugin.getServerMaxKeyLength(),
server_max_value_length=memcached_plugin.getServerMaxValueLength())
local_dict[plugin_path] = dictionary
return dictionary
security.declareProtected(Permissions.AccessContentsInformation, 'getMemcachedDict') security.declareProtected(Permissions.AccessContentsInformation, 'getMemcachedDict')
def getMemcachedDict(self, key_prefix, plugin_path): def getMemcachedDict(self, key_prefix, plugin_path):
""" """
...@@ -302,10 +277,14 @@ if memcache is not None: ...@@ -302,10 +277,14 @@ if memcache is not None:
plugin_path plugin_path
relative_url of dedicated Memcached Plugin relative_url of dedicated Memcached Plugin
""" """
memcached_plugin = self.restrictedTraverse(plugin_path, None)
if memcached_plugin is None:
raise ValueError('Memcached Plugin does not exists: %r' % (
plugin_path, ))
global_prefix = self.erp5_site_global_id global_prefix = self.erp5_site_global_id
if global_prefix: if global_prefix:
key_prefix = '%s_%s' % (global_prefix, key_prefix) key_prefix = global_prefix + '_' + key_prefix
return SharedDict(self._getMemcachedDict(plugin_path), prefix=key_prefix) return SharedDict(memcached_plugin.getConnection(), prefix=key_prefix)
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