Commit 623c7f78 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 310efcbd
...@@ -153,20 +153,27 @@ class ZSync: ...@@ -153,20 +153,27 @@ class ZSync:
zsync.zconn = zconn # XXX -> weakref zsync.zconn = zconn # XXX -> weakref
zsync.wconn = wconn zsync.wconn = wconn
# when connection will be reopened -> zsync.on_connection_open() # NOTE zcon.onOpenCallback is not enought: zconn.at can change even
zconn.onOpenCallback(zsync) # without zconn.close/zconn.open, e.g.:
# zconn = DB.open(transaction_manager=tm)
# tm.commit() # zconn.at updated (zconn.afterCompletion -> zconn.newTransaction)
# tm.commit() # zconn.at updated again
#
# TODO test for that.
#zconn.onOpenCallback(zsync)
zconn.onResyncCallback(zsync)
"""
# DB.open() pops .zconn from connection pool and "opens" for usage. # DB.open() pops .zconn from connection pool and "opens" for usage.
# -> resync .wconn to new database view of ZODB connection. # -> resync .wconn to new database view of ZODB connection.
# #
# FIXME zconn.at can change even without zconn.close/zconn.open, e.g.:
# zconn = DB.open(transaction_manager=tm)
# tm.commit() # zconn.at updated (zconn.afterCompletion -> zconn.newTransaction)
# tm.commit() # zconn.at updated again
#
# TODO fix/test for that.
def on_connection_open(zsync): def on_connection_open(zsync):
print('ZSync.resync %r %r' % (zsync.zconn, zsync.wconn)) print('ZSync.resync %r %r' % (zsync.zconn, zsync.wconn))
zsync.wconn.resync(zconn_at(zsync.zconn)) zsync.wconn.resync(zconn_at(zsync.zconn))
"""
def on_connection_resync(zsync):
print('ZSync.resync %r %r' % (zsync.zconn, zsync.wconn))
zsync.wconn.resync(zconn_at(zsync.zconn))
# TODO zconn dealloc -> wconn.close # TODO zconn dealloc -> wconn.close
...@@ -24,6 +24,7 @@ from ZODB.FileStorage import FileStorage ...@@ -24,6 +24,7 @@ from ZODB.FileStorage import FileStorage
from ZODB import DB from ZODB import DB
from ZODB.utils import p64, u64 from ZODB.utils import p64, u64
from persistent import Persistent from persistent import Persistent
from weakref import WeakSet
import gc import gc
import pkg_resources import pkg_resources
...@@ -192,3 +193,35 @@ def _zmajor(): ...@@ -192,3 +193,35 @@ def _zmajor():
# zmajor is set to major ZODB version. # zmajor is set to major ZODB version.
zmajor = _zmajor() zmajor = _zmajor()
# patch for ZODB.Connection to support callback on after database view is changed
ZODB.Connection.Connection._onResyncCallbacks = None
def Connection_onResyncCallback(self, f):
if self._onResyncCallbacks is None:
# NOTE WeakSet does not work for bound methods - they are always created
# anew for each obj.method access, and thus will go away almost immediately
self._onResyncCallbacks = WeakSet()
assert not hasattr(ZODB.Connection.Connection, 'onResyncCallback')
ZODB.Connection.Connection.onResyncCallback = Connection_onResyncCallback
# ZODB5: hook into Connection.newTransaction XXX .newTransaction .afterCompletion ?
# ZODB4: hook into Connection._storage_sync XXX .newTransaction .afterCompletion ?
# ZODB3: TODO
# XXX ZODB5 only for now
# XXX ERP5Type/patches/ZODBConnection.py overrides newTransaction without calling orig_newTransaction
# -> fix it there.
_orig_Connection_newTransaction = ZODB.Connection.Connection.newTransaction
def _ZConnection_newTransaction(self, transaction, sync=True):
_orig_Connection_newTransaction(self, transaction, sync)
# FIXME method name hardcoded. Better not do it and allow f to be general
# callable, but that does not work with bound method - see above.
# ( Something like WeakMethod from py3 could help )
if self._onResyncCallbacks:
for f in self._onResyncCallbacks:
f.on_connection_resync()
ZODB.Connection.Connection.newTransaction = _ZConnection_newTransaction
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