Commit e5cb7960 authored by Vincent Pelletier's avatar Vincent Pelletier Committed by Jérome Perrin

synchronizeDynamicModules: Flush ZODB cache.

Should fix most of the cases where reloading components cause breakage.
There is still a race condition between a transaction's cache being
actually flushed (which can only happen at transaction boundaries) and
another transaction doing the actual class reload, which will
immediately affect all the started transactions in the same process.
parent 1f69c0d7
Pipeline #11243 failed with stage
in 0 seconds
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
import os import os
import inspect import inspect
import transaction import transaction
from ZODB import Connection
from Products.ERP5Type.mixin.temporary import TemporaryDocumentMixin from Products.ERP5Type.mixin.temporary import TemporaryDocumentMixin
from Products.ERP5Type.Base import resetRegisteredWorkflowMethod from Products.ERP5Type.Base import resetRegisteredWorkflowMethod
...@@ -390,6 +391,24 @@ def synchronizeDynamicModules(context, force=False): ...@@ -390,6 +391,24 @@ def synchronizeDynamicModules(context, force=False):
return return
last_sync = cookie last_sync = cookie
# Flush the entire ZODB.Connections pickle cache on next opening
# (transaction beginning), for all connections.
# There may be instances of the classes which are being reloaded in the
# cache, and the code change may cause incompatible instance property
# layouts. A very visible example is if the class does not exist prior to
# the reload: if any instance was loaded, it is loaded as an instance of
# the Broken class, which has a __setstate__ method which mangles
# instance's properties. Then, post-reload the class cannot expect to
# handle an instance with such property mangling, and will start behaving
# in undefined ways.
# Strictly, this issue also applies to any non-persistent instance of any
# class defined in (or affected by) anything being reloaded. But as these
# instances have not been made persistent, there is no guarantee that they
# can be reloaded in any way.
# Emptying the ZODB cache is the last thing short of restarting the whole
# process.
Connection.resetCaches()
import erp5 import erp5
with aq_method_lock: with aq_method_lock:
# Thanks to TransactionalResource, the '_bootstrapped' global variable # Thanks to TransactionalResource, the '_bootstrapped' global variable
......
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