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 @@ ...@@ -30,12 +30,14 @@
import transaction import transaction
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type import Permissions 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 Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from zLOG import LOG, INFO, WARNING from zLOG import LOG, INFO, WARNING
_last_sync = -1
class ComponentTool(BaseTool): class ComponentTool(BaseTool):
""" """
This tool provides methods to load the the different types This tool provides methods to load the the different types
...@@ -50,38 +52,52 @@ class ComponentTool(BaseTool): ...@@ -50,38 +52,52 @@ class ComponentTool(BaseTool):
security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.ModifyPortalContent, 'reset') security.declareProtected(Permissions.ModifyPortalContent, 'reset')
def reset(self, is_sync=False): def reset(self, force=True):
""" """
XXX-arnau: global reset XXX-arnau: global reset
""" """
LOG("ERP5Type.Tool.ComponentTool", INFO, "Resetting Components")
import erp5.component
portal = self.getPortalObject() 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') 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 type_tool = portal.portal_types
container_type_info = type_tool.getTypeInfo(self.getPortalType())
for content_type in container_type_info.getTypeAllowedContentTypeList(): allowed_content_type_list = type_tool.getTypeInfo(
module_name = content_type.split(' ')[0].lower() self.getPortalType()).getTypeAllowedContentTypeList()
try: import erp5.component
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) 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() type_tool.resetDynamicDocumentsOnceAtTransactionBoundary()
......
...@@ -28,33 +28,6 @@ ...@@ -28,33 +28,6 @@
from Products.ERP5.ERP5Site import getSite from Products.ERP5.ERP5Site import getSite
from types import ModuleType 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 from zLOG import LOG, INFO
def generateComponentClassWrapper(namespace, portal_type): def generateComponentClassWrapper(namespace, portal_type):
......
...@@ -122,9 +122,9 @@ def initializeDynamicModules(): ...@@ -122,9 +122,9 @@ def initializeDynamicModules():
loadTempPortalTypeClass) loadTempPortalTypeClass)
# Components # 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 sys.modules["erp5.component"] = erp5.component
erp5.component.extension = registerDynamicModule( 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