Commit 195940fb authored by Arnaud Fontaine's avatar Arnaud Fontaine

Avoid regeneration of classes when starting a node within a cluster with already started nodes.

When starting a node, ERP5Site.__of__ calls ComponentTool.reset(), which was
never synchronised so it returned True (without generating a new cookie at its
level) and causing synchronizeDynamicModules to be called with
force=True. This generated a new cookie and leading to dynamic classes being
meaninglessly regenerated on all nodes.

Instead, modify ComponentTool.reset() behavior so it *always* reset Portal
Type classes when Components are reset (as it should have always been as the
class inheritance may have been modified) and force regeneration of Portal
Type classes in this method if reset is True.

Signed-off: Vincent Pelletier <vincent@nexedi.com>
parent 60ab44fb
...@@ -4053,13 +4053,15 @@ class DocumentTemplateItem(FilesystemToZodbTemplateItem): ...@@ -4053,13 +4053,15 @@ class DocumentTemplateItem(FilesystemToZodbTemplateItem):
if self._is_already_migrated(object_list): if self._is_already_migrated(object_list):
ObjectTemplateItem.install(self, context, **kw) ObjectTemplateItem.install(self, context, **kw)
self.portal_components.reset(force=True, reset_portal_type=True) self.portal_components.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
else: else:
FilesystemDocumentTemplateItem.install(self, context, **kw) FilesystemDocumentTemplateItem.install(self, context, **kw)
def afterUninstall(self, already_migrated=False): def afterUninstall(self, already_migrated=False):
if already_migrated: if already_migrated:
self.portal_components.reset(force=True, reset_portal_type=True) self.portal_components.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
class ExtensionTemplateItem(DocumentTemplateItem): class ExtensionTemplateItem(DocumentTemplateItem):
""" """
......
...@@ -347,8 +347,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin): ...@@ -347,8 +347,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
# This should only happen before erp5_core is installed # This should only happen before erp5_core is installed
synchronizeDynamicModules(self) synchronizeDynamicModules(self)
else: else:
# If Components are reset, then portal type classes should be reset component_tool.reset()
synchronizeDynamicModules(self, component_tool.reset())
return self return self
......
...@@ -62,7 +62,9 @@ class ComponentTool(BaseTool): ...@@ -62,7 +62,9 @@ class ComponentTool(BaseTool):
security.declareObjectProtected(Permissions.AccessContentsInformation) security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.ResetDynamicClasses, 'reset') security.declareProtected(Permissions.ResetDynamicClasses, 'reset')
def reset(self, force=False, reset_portal_type=False): def reset(self,
force=False,
reset_portal_type_at_transaction_boundary=False):
""" """
Reset all ZODB Component packages. A cache cookie is used to check whether Reset all ZODB Component packages. A cache cookie is used to check whether
the reset is necessary when force is not specified. This allows to make the reset is necessary when force is not specified. This allows to make
...@@ -115,8 +117,11 @@ class ComponentTool(BaseTool): ...@@ -115,8 +117,11 @@ class ComponentTool(BaseTool):
else: else:
package.reset() package.reset()
if reset_portal_type: if reset_portal_type_at_transaction_boundary:
type_tool.resetDynamicDocumentsOnceAtTransactionBoundary() type_tool.resetDynamicDocumentsOnceAtTransactionBoundary()
else:
from Products.ERP5Type.dynamic.portal_type_class import synchronizeDynamicModules
synchronizeDynamicModules(self, force)
return True return True
......
...@@ -1282,7 +1282,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase): ...@@ -1282,7 +1282,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self._component_tool = self.getPortal().portal_components self._component_tool = self.getPortal().portal_components
self._module = __import__(self._getComponentModuleName(), self._module = __import__(self._getComponentModuleName(),
fromlist=['erp5.component']) fromlist=['erp5.component'])
self._component_tool.reset(force=True, reset_portal_type=True) self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
@abc.abstractmethod @abc.abstractmethod
def _newComponent(self, reference, text_content, version='erp5'): def _newComponent(self, reference, text_content, version='erp5'):
...@@ -1413,7 +1414,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase): ...@@ -1413,7 +1414,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self.assertEquals(error_message, error_list[0]) self.assertEquals(error_message, error_list[0])
self.assertEquals(component.getReference(), invalid_reference) self.assertEquals(component.getReference(), invalid_reference)
self.assertEquals(component.getReference(validated_only=True), valid_reference) self.assertEquals(component.getReference(validated_only=True), valid_reference)
self._component_tool.reset(force=True, reset_portal_type=True) self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
self.assertModuleImportable(valid_reference) self.assertModuleImportable(valid_reference)
# Set a valid reference and check that the Component is in validated state # Set a valid reference and check that the Component is in validated state
...@@ -1490,7 +1492,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase): ...@@ -1490,7 +1492,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self.assertEquals(error_message, error_list[0]) self.assertEquals(error_message, error_list[0])
self.assertEquals(component.getVersion(), invalid_version) self.assertEquals(component.getVersion(), invalid_version)
self.assertEquals(component.getVersion(validated_only=True), valid_version) self.assertEquals(component.getVersion(validated_only=True), valid_version)
self._component_tool.reset(force=True, reset_portal_type=True) self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
self.assertModuleImportable(reference) self.assertModuleImportable(reference)
# Set a valid version and check that the Component is in validated state # Set a valid version and check that the Component is in validated state
...@@ -1564,7 +1567,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase): ...@@ -1564,7 +1567,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self.assertTrue(error_list[0].startswith(error_message)) self.assertTrue(error_list[0].startswith(error_message))
self.assertEquals(component.getTextContent(), invalid_code) self.assertEquals(component.getTextContent(), invalid_code)
self.assertEquals(component.getTextContent(validated_only=True), valid_code) self.assertEquals(component.getTextContent(validated_only=True), valid_code)
self._component_tool.reset(force=True, reset_portal_type=True) self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
self.assertModuleImportable('TestComponentWithSyntaxError') self.assertModuleImportable('TestComponentWithSyntaxError')
# Set a valid source code and check that the Component is in validated # Set a valid source code and check that the Component is in validated
...@@ -1892,7 +1896,8 @@ class TestPortalType(Person): ...@@ -1892,7 +1896,8 @@ class TestPortalType(Person):
self.assertFalse(self._module.TestPortalType in person.__class__.mro()) self.assertFalse(self._module.TestPortalType in person.__class__.mro())
# Reset Portal Type classes to ghost to make sure that everything is reset # Reset Portal Type classes to ghost to make sure that everything is reset
self._component_tool.reset(force=True, reset_portal_type=True) self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
# TestPortalType must be available in type class list # TestPortalType must be available in type class list
self.assertTrue('TestPortalType' in person_type.getDocumentTypeList()) self.assertTrue('TestPortalType' in person_type.getDocumentTypeList())
...@@ -2017,7 +2022,8 @@ class Test(ERP5TypeTestCase): ...@@ -2017,7 +2022,8 @@ class Test(ERP5TypeTestCase):
self.assertEqual(component.getValidationState(), 'validated') self.assertEqual(component.getValidationState(), 'validated')
self.assertModuleImportable('testRunLiveTest') self.assertModuleImportable('testRunLiveTest')
self._component_tool.reset(force=True, reset_portal_type=True) self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
# ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it # ERP5TypeLiveTestCase.runLiveTest patches ERP5TypeTestCase bases, thus it
# needs to be restored after calling runLiveTest # needs to be restored after calling runLiveTest
...@@ -2045,7 +2051,8 @@ class Test(ERP5TypeTestCase): ...@@ -2045,7 +2051,8 @@ class Test(ERP5TypeTestCase):
self.assertEqual(component.getValidationState(), 'validated') self.assertEqual(component.getValidationState(), 'validated')
self.assertModuleImportable('testRunLiveTest') self.assertModuleImportable('testRunLiveTest')
self._component_tool.reset(force=True, reset_portal_type=True) self._component_tool.reset(force=True,
reset_portal_type_at_transaction_boundary=True)
base_tuple = ERP5TypeTestCase.__bases__ base_tuple = ERP5TypeTestCase.__bases__
try: try:
......
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