From 95a7530300aaba951df161d77bbc3fb228335f56 Mon Sep 17 00:00:00 2001 From: Julien Muchembled <jm@nexedi.com> Date: Wed, 2 Dec 2020 16:37:48 +0100 Subject: [PATCH] Fix some monkey-patches to make them compatible with ZODB5 See also https://github.com/zopefoundation/ZEO/pull/63 and https://lab.nexedi.com/nexedi/erp5/merge_requests/1095 No error in testCMFActivity and testConflictResolution. For the only error in testInvalidationBug, see comment. But this commit is not enough for ZODB5. The only known issue so far is the use of newer pickle protocol, which breaks export of ZODB data and requires non-trivial changes in our XMLExportImport/ppml code. So for the moment, many failures in testBusinessTempate. --- product/ERP5/tests/testInvalidationBug.py | 3 ++ product/ERP5Type/patches/DemoStorage.py | 3 +- product/ERP5Type/patches/XMLExportImport.py | 4 +-- product/ERP5Type/patches/ZODBConnection.py | 35 +++++++++------------ product/ERP5Type/tests/custom_zodb.py | 5 ++- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/product/ERP5/tests/testInvalidationBug.py b/product/ERP5/tests/testInvalidationBug.py index 5251983929..af721dd02d 100644 --- a/product/ERP5/tests/testInvalidationBug.py +++ b/product/ERP5/tests/testInvalidationBug.py @@ -90,6 +90,9 @@ class TestInvalidationBug(ERP5TypeTestCase): self.assertEqual(result_list[-2], None) # ZODB self.assertEqual(result_list[-1], [1,1]) # activity tables last + # TODO: - skip this test for ZEO>=5 because it's covered upstream + # (and later remove it) + # - in slapos.git, enable server_sync in zope.conf def testLateInvalidationFromZEO(self): ### Check unit test is run properly from ZEO.ClientStorage import ClientStorage diff --git a/product/ERP5Type/patches/DemoStorage.py b/product/ERP5Type/patches/DemoStorage.py index 87ce80303f..0803eab458 100644 --- a/product/ERP5Type/patches/DemoStorage.py +++ b/product/ERP5Type/patches/DemoStorage.py @@ -13,7 +13,7 @@ ############################################################################## from ZODB import DemoStorage as _DemoStorage -from ZODB.ConflictResolution import ConflictResolvingStorage, ResolvedSerial +from ZODB.ConflictResolution import ConflictResolvingStorage from ZODB.POSException import ConflictError class DemoStorage(_DemoStorage.DemoStorage, ConflictResolvingStorage): @@ -33,4 +33,5 @@ class DemoStorage(_DemoStorage.DemoStorage, ConflictResolvingStorage): if not issubclass(_DemoStorage.DemoStorage, ConflictResolvingStorage): # BBB: ZODB < 4.3 + from ZODB.ConflictResolution import ResolvedSerial _DemoStorage.DemoStorage = DemoStorage diff --git a/product/ERP5Type/patches/XMLExportImport.py b/product/ERP5Type/patches/XMLExportImport.py index fd8bdbcf59..5f8f689901 100644 --- a/product/ERP5Type/patches/XMLExportImport.py +++ b/product/ERP5Type/patches/XMLExportImport.py @@ -107,9 +107,7 @@ def exportXML(jar, oid, file=None): def getReorderedPickle(oid): p = pickle_dict[oid] if p is None: - # Versions are ignored, but some 'load()' implementations require them - # FIXME: remove "''" when TmpStore.load() on ZODB stops asking for it. - p = load(oid, '')[0] + p = load(oid)[0] p = reorderPickle(jar, p)[1] if len(p) < max_cache[0]: max_cache[0] -= len(p) diff --git a/product/ERP5Type/patches/ZODBConnection.py b/product/ERP5Type/patches/ZODBConnection.py index 7626943056..eda7aa9d95 100644 --- a/product/ERP5Type/patches/ZODBConnection.py +++ b/product/ERP5Type/patches/ZODBConnection.py @@ -11,36 +11,29 @@ # ############################################################################## -# override ZODB.Connection.newTransaction() to do a synchronous call before -# flushing all invalidations, this will serve as a "network barrier" that -# will force Connection to wait for all invalidations sent from other parallel -# transactions so that, for instance, activity processing can see a recent -# enough state of the ZODB. - import time from Products.ERP5Type.Timeout import TimeoutReachedError, getDeadline from ZODB.Connection import Connection FORCE_STORAGE_SYNC_ON_CONNECTION_OPENING = False -if 1: # keep indentation. Also good for quick disabling. +if 1: # for quick disabling. - def ping(self): - # Use a synchronous call to make sure we have received all invalidation - # methods that could be stuck in the wire so MVCC behaves correctly. - # XXX Use a proper ping method exported by ClientStorage instead of - # this hack - ping = getattr(getattr(self._storage, '_server', None), - 'getAuthProtocol', - lambda: None) - ping() + if hasattr(Connection, '_storage_sync'): # ZODB<5 + # BBB: For ZEO<5, use a synchronous call to make sure we have received + # all invalidation methods that could be stuck in the wire so MVCC + # behaves correctly. This can be seen as a "network barrier", + # so that, for instance, activity processing can see a recent + # enough state of the ZODB. + # ZEO5 has an option and NEO does it by default. - def newTransaction(self, *ignored): - self.ping() - self._storage_sync() + def newTransaction(self, *ignored): + zeo = getattr(self._storage, '_server', None) + if zeo is not None: + zeo.getAuthProtocol() + self._storage_sync() - Connection.ping = ping - Connection.newTransaction = newTransaction + Connection.newTransaction = newTransaction if FORCE_STORAGE_SYNC_ON_CONNECTION_OPENING: diff --git a/product/ERP5Type/tests/custom_zodb.py b/product/ERP5Type/tests/custom_zodb.py index 0a2bed44f5..15f2ebb339 100644 --- a/product/ERP5Type/tests/custom_zodb.py +++ b/product/ERP5Type/tests/custom_zodb.py @@ -168,7 +168,10 @@ else: else: forkNodes() from ZEO.ClientStorage import ClientStorage - Storage = ClientStorage(zeo_client) + try: + Storage = ClientStorage(zeo_client, server_sync=True) + except TypeError: # BBB: ZEO<5 + Storage = ClientStorage(zeo_client) if node_pid_list is not None: _print("Instance at %r loaded ... " % instance_home) -- 2.30.9