Commit 347b899b authored by Arnaud Fontaine's avatar Arnaud Fontaine

Avoid costly checking if Component modules are synchronized on __getattribute__.

parent 5f22a089
......@@ -30,12 +30,14 @@
import transaction
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type import Permissions
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type.Base import Base
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from zLOG import LOG, INFO, WARNING
_last_sync = -1
class ComponentTool(BaseTool):
"""
This tool provides methods to load the the different types
......@@ -50,38 +52,52 @@ class ComponentTool(BaseTool):
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.ModifyPortalContent, 'reset')
def reset(self, is_sync=False):
def reset(self, force=True):
"""
XXX-arnau: global reset
"""
LOG("ERP5Type.Tool.ComponentTool", INFO, "Resetting Components")
import erp5.component
portal = self.getPortalObject()
if not is_sync:
# XXX-arnau: copy/paste from portal_type_class, but is this really
# necessary as even for Portal Type classes, synchronizeDynamicModules
# seems to always called with force=True?
global last_sync
if force:
# hard invalidation to force sync between nodes
portal.newCacheCookie('component_classes')
erp5.component._last_reset = portal.getCacheCookie('component_classes')
last_sync = portal.getCacheCookie('component_classes')
else:
cookie = portal.getCacheCookie('component_classes')
if cookie == last_sync:
type_tool.resetDynamicDocumentsOnceAtTransactionBoundary()
return
last_sync = cookie
LOG("ERP5Type.Tool.ComponentTool", INFO, "Resetting Components")
type_tool = portal.portal_types
container_type_info = type_tool.getTypeInfo(self.getPortalType())
for content_type in container_type_info.getTypeAllowedContentTypeList():
module_name = content_type.split(' ')[0].lower()
allowed_content_type_list = type_tool.getTypeInfo(
self.getPortalType()).getTypeAllowedContentTypeList()
try:
module = getattr(erp5.component, module_name)
# XXX-arnau: not everything is defined yet...
except AttributeError:
pass
else:
for name in module.__dict__.keys():
if name[0] != '_':
LOG("ERP5Type.Tool.ComponentTool", INFO,
"Resetting erp5.component.%s.%s" % (module_name, name))
import erp5.component
delattr(module, name)
with Base.aq_method_lock:
for content_type in allowed_content_type_list:
module_name = content_type.split(' ')[0].lower()
try:
module = getattr(erp5.component, module_name)
# XXX-arnau: not everything is defined yet...
except AttributeError:
pass
else:
for name in module.__dict__.keys():
if name[0] != '_':
LOG("ERP5Type.Tool.ComponentTool", INFO,
"Resetting erp5.component.%s.%s" % (module_name, name))
delattr(module, name)
type_tool.resetDynamicDocumentsOnceAtTransactionBoundary()
......
......@@ -28,33 +28,6 @@
from Products.ERP5.ERP5Site import getSite
from types import ModuleType
class ComponentModule(ModuleType):
_resetting = False
_last_reset = -1
def __getattribute__(self, name):
"""
Synchronize between ZEO clients
XXX-arnau: surely bad from a performance POV and not thread-safe
"""
if name[0] == '_' or self._resetting:
return super(ComponentModule, self).__getattribute__(name)
import erp5.component
site = getSite()
cookie = site.getCacheCookie('component_classes')
if self._last_reset == -1:
self._last_reset = site.getCacheCookie('component_classes')
elif cookie != self._last_reset:
self._resetting = True
site.portal_components.reset(is_sync=True)
self._resetting = False
return super(ComponentModule, self).__getattribute__(name)
from types import ModuleType
from zLOG import LOG, INFO
def generateComponentClassWrapper(namespace, portal_type):
......
......@@ -122,9 +122,9 @@ def initializeDynamicModules():
loadTempPortalTypeClass)
# Components
from component_class import ComponentModule, generateComponentClassWrapper
from component_class import generateComponentClassWrapper
erp5.component = ComponentModule("erp5.component")
erp5.component = ModuleType("erp5.component")
sys.modules["erp5.component"] = erp5.component
erp5.component.extension = registerDynamicModule(
......
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