Commit c5f44743 authored by Nicolas Dumazet's avatar Nicolas Dumazet

Clean up code related to Dynamic modules invalidation:

* add CacheCookieMixin to ERP5Site and use its methods
  instead of manually using ZODBCookie's
* rename resetDynamicDocuments to synchronizeDynamicModules
  to clarify its role.
* use "force" instead of "slave" and document the meaning
  more clearly
* put all cookie-related code inside synchronizeDynamicModules


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@38666 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 8f4e8ae5
......@@ -29,7 +29,7 @@ from Acquisition import aq_base
from Products.ERP5Type import allowClassTool
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.Cache import caching_instance_method
from Products.ERP5Type.Cache import CachingMethod
from Products.ERP5Type.Cache import CachingMethod, CacheCookieMixin
from Products.ERP5Type.ERP5Type import ERP5TypeInformation
from Products.ERP5.Document.BusinessTemplate import BusinessTemplate
from Products.ERP5Type.Log import log as unrestrictedLog
......@@ -178,7 +178,7 @@ class ReferCheckerBeforeTraverseHook:
'request : "%s"' % http_url)
response.unauthorized()
class ERP5Site(FolderMixIn, CMFSite):
class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
"""
The *only* function this class should have is to help in the setup
of a new ERP5. It should not assist in the functionality at all.
......
......@@ -9,10 +9,10 @@ from types import ModuleType
from Products.ERP5Type.patches.getSite import getSite
from Products.ERP5Type.Globals import InitializeClass
from Products.ERP5Type.Utils import setDefaultClassProperties
from Products.ERP5Type.Cache import ZODBCookie
from Products.ERP5Type import document_class_registry, mixin_class_registry
from ExtensionClass import Base as ExtensionBase
from zLOG import LOG, ERROR, BLATHER
def _import_class(classpath):
......@@ -167,17 +167,35 @@ def initializeDynamicModules():
temp_portal_type_loader)
from ExtensionClass import Base as ExtensionBase
def resetDynamicDocuments(context, slave=False):
last_sync = 0
def synchronizeDynamicModules(context, force=False):
"""
Allow resetting all classes to ghost state, most likely done after
adding and removing mixins on the fly
Nodes just trying to catch up with state of classes without wanting
to invalidate them globally should set slave=True.
Most of the time, this reset is only hypothetic:
* with force=False, the reset is only done if another node resetted
the classes since the last reset on this node.
* with force=True, forcefully reset the classes on the current node
and send out an invalidation to other nodes
"""
LOG("ERP5Type.Dynamic", 0, "Resetting dynamic classes")
return # XXX disabled for now
portal = context.getPortalObject()
global last_sync
if force:
# hard invalidation to force sync between nodes
portal.newCacheCookie('dynamic_classes')
last_sync = portal.getCacheCookie('dynamic_classes')
else:
cookie = portal.getCacheCookie('dynamic_classes')
if cookie == last_sync:
# up to date, nothing to do
return
last_sync = cookie
import erp5.portal_type
for class_name, klass in inspect.getmembers(erp5.portal_type, inspect.isclass):
ghostbase = getattr(klass, '__ghostbase__', None)
......@@ -188,12 +206,3 @@ def resetDynamicDocuments(context, slave=False):
klass.__bases__ = ghostbase
type(ExtensionBase).__init__(klass, klass)
if not slave:
# hard invalidation to force sync between nodes
portal = context.getPortalObject()
cookie = getattr(portal, '_dynamic_class_cookie', None)
if cookie is not None:
cookie.value += 1
else:
portal._dynamic_class_cookie = ZODBCookie()
......@@ -29,6 +29,7 @@ from Products.ERP5Type.ERP5Type import ERP5TypeInformation
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from zLOG import LOG, WARNING, PANIC
from Products.ERP5Type.interfaces import ITypeProvider, ITypesTool
from Products.ERP5Type.Dynamic.portaltypeclass import synchronizeDynamicModules
class ComposedObjectIds(object):
......@@ -244,8 +245,7 @@ class TypesTool(TypeProvider):
'resetDynamicDocuments')
def resetDynamicDocuments(self):
"""Resets all dynamic documents: force reloading erp.* classes"""
from Products.ERP5Type.Dynamic.portaltypeclass import resetDynamicDocuments
resetDynamicDocuments(self)
synchronizeDynamicModules(self, force=True)
security.declareProtected(Permissions.AddPortalContent,
'manage_addTypeInformation')
......
from Products.ERP5Type.Dynamic.portaltypeclass import synchronizeDynamicModules
from Products.ERP5Type import Globals
module_name = 'zope.site.hooks'
try:
......@@ -37,13 +38,5 @@ hooks.getSite = getSite
last_cookie_value = None
def setSite(site=None):
_setSite(site)
cookie = getattr(site, '_dynamic_class_cookie', None)
if cookie is not None:
global last_cookie_value
if cookie.value != last_cookie_value:
# some other node changed a portal type
# reload locally the dynamic classes
from Products.ERP5Type.Dynamic.portaltypeclass import resetDynamicDocuments
resetDynamicDocuments(site, slave=True)
last_cookie_value = cookie.value
synchronizeDynamicModules(site)
hooks.setSite = setSite
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