Commit 11f57b83 authored by Julien Muchembled's avatar Julien Muchembled

bootstrap: retry migration if previous transaction failed

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@45644 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 5d3fc674
......@@ -59,6 +59,8 @@ import warnings
from UserDict import IterableUserDict
from Shared.DC.ZRDB.TM import TM
from threading import local
import transaction.interfaces
import zope.interface
class TransactionalVariable(TM, IterableUserDict):
"""TransactionalVariable provides a dict-like look-n-feel.
......@@ -97,3 +99,25 @@ def getTransactionalVariable(context=_MARKER):
tv = TransactionalVariable()
transactional_variable_pool.instance = tv
return tv
class TransactionalResource(object):
zope.interface.implements(transaction.interfaces.IDataManager)
def __init__(self, transaction_manager=None, **kw):
if transaction_manager is None:
from transaction import manager as transaction_manager
self.__dict__.update(kw, transaction_manager=transaction_manager)
transaction_manager.get().join(self)
@classmethod
def registerOnce(cls, *args):
tv = getTransactionalVariable().setdefault(cls, set())
return not (args in tv or tv.add(args))
def sortKey(self):
return 1
abort = commit = tpc_vote = tpc_begin = tpc_finish = tpc_abort = \
lambda self, transaction: None
......@@ -40,6 +40,7 @@ from Products.ERP5Type.Utils import setDefaultClassProperties
from Products.ERP5Type import document_class_registry, mixin_class_registry
from Products.ERP5Type.dynamic.accessor_holder import AccessorHolderModuleType, \
createAllAccessorHolderList
from Products.ERP5Type.TransactionalVariable import TransactionalResource
from zLOG import LOG, ERROR, INFO, WARNING
......@@ -337,7 +338,11 @@ def synchronizeDynamicModules(context, force=False):
Base.aq_method_lock.acquire()
try:
if portal.id not in _bootstrapped:
# Thanks to TransactionalResource, the '_bootstrapped' global variable
# is updated in a transactional way. Without it, it would be required to
# restart the instance if anything went wrong.
if portal.id not in _bootstrapped and \
TransactionalResource.registerOnce(__name__, 'bootstrap', portal.id):
migrate = False
from Products.ERP5Type.Tool.PropertySheetTool import PropertySheetTool
from Products.ERP5Type.Tool.TypesTool import TypesTool
......@@ -366,10 +371,12 @@ def synchronizeDynamicModules(context, force=False):
if PickleUpdater.get:
portal.migrateToPortalTypeClass()
portal.portal_skins.changeSkin(None)
TransactionalResource(tpc_finish=lambda txn:
_bootstrapped.add(portal.id))
LOG('ERP5Site', INFO, 'Transition successful, please update your'
' business templates')
_bootstrapped.add(portal.id)
else:
_bootstrapped.add(portal.id)
LOG("ERP5Type.dynamic", 0, "Resetting dynamic classes")
try:
......
......@@ -54,6 +54,11 @@ implements_tuple_list = [
class TestERP5TypeInterfaces(ERP5TypeTestCase):
"""Tests implementation of interfaces"""
def testTransactionalResource(self):
from Products.ERP5Type.TransactionalVariable import TransactionalResource
from transaction.interfaces import IDataManager
verifyClass(IDataManager, TransactionalResource)
def makeTestMethod(import_tuple, interface):
"""Common method which checks if documents implements interface"""
def testMethod(self):
......
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