Commit 20362ede 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-by: Vincent Pelletier's avatarVincent Pelletier <vincent@nexedi.com>
parent 8a86bed5
......@@ -4020,13 +4020,15 @@ class DocumentTemplateItem(FilesystemToZodbTemplateItem):
if self._is_already_migrated(object_list):
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:
FilesystemDocumentTemplateItem.install(self, context, **kw)
def afterUninstall(self, already_migrated=False):
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):
"""
......
......@@ -347,8 +347,7 @@ class ERP5Site(FolderMixIn, CMFSite, CacheCookieMixin):
# This should only happen before erp5_core is installed
synchronizeDynamicModules(self)
else:
# If Components are reset, then portal type classes should be reset
synchronizeDynamicModules(self, component_tool.reset())
component_tool.reset()
return self
......
......@@ -62,7 +62,9 @@ class ComponentTool(BaseTool):
security.declareObjectProtected(Permissions.AccessContentsInformation)
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
the reset is necessary when force is not specified. This allows to make
......@@ -115,8 +117,11 @@ class ComponentTool(BaseTool):
else:
package.reset()
if reset_portal_type:
if reset_portal_type_at_transaction_boundary:
type_tool.resetDynamicDocumentsOnceAtTransactionBoundary()
else:
from Products.ERP5Type.dynamic.portal_type_class import synchronizeDynamicModules
synchronizeDynamicModules(self, force)
return True
......
......@@ -1282,7 +1282,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self._component_tool = self.getPortal().portal_components
self._module = __import__(self._getComponentModuleName(),
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
def _newComponent(self, reference, text_content, version='erp5'):
......@@ -1413,7 +1414,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self.assertEquals(error_message, error_list[0])
self.assertEquals(component.getReference(), invalid_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)
# Set a valid reference and check that the Component is in validated state
......@@ -1490,7 +1492,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self.assertEquals(error_message, error_list[0])
self.assertEquals(component.getVersion(), invalid_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)
# Set a valid version and check that the Component is in validated state
......@@ -1564,7 +1567,8 @@ class _TestZodbComponent(TestDeveloperMixin, SecurityTestCase):
self.assertTrue(error_list[0].startswith(error_message))
self.assertEquals(component.getTextContent(), invalid_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')
# Set a valid source code and check that the Component is in validated
......@@ -1892,7 +1896,8 @@ class TestPortalType(Person):
self.assertFalse(self._module.TestPortalType in person.__class__.mro())
# 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
self.assertTrue('TestPortalType' in person_type.getDocumentTypeList())
......@@ -2017,7 +2022,8 @@ class Test(ERP5TypeTestCase):
self.assertEqual(component.getValidationState(), 'validated')
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
# needs to be restored after calling runLiveTest
......@@ -2045,7 +2051,8 @@ class Test(ERP5TypeTestCase):
self.assertEqual(component.getValidationState(), 'validated')
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__
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