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

.

parent 310efcbd
......@@ -153,20 +153,27 @@ class ZSync:
zsync.zconn = zconn # XXX -> weakref
zsync.wconn = wconn
# when connection will be reopened -> zsync.on_connection_open()
zconn.onOpenCallback(zsync)
# DB.open() pops .zconn from connection pool and "opens" for usage.
# -> resync .wconn to new database view of ZODB connection.
#
# FIXME zconn.at can change even without zconn.close/zconn.open, e.g.:
# NOTE zcon.onOpenCallback is not enought: 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.
# TODO test for that.
#zconn.onOpenCallback(zsync)
zconn.onResyncCallback(zsync)
"""
# DB.open() pops .zconn from connection pool and "opens" for usage.
# -> resync .wconn to new database view of ZODB connection.
#
def on_connection_open(zsync):
print('ZSync.resync %r %r' % (zsync.zconn, zsync.wconn))
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
......@@ -24,6 +24,7 @@ from ZODB.FileStorage import FileStorage
from ZODB import DB
from ZODB.utils import p64, u64
from persistent import Persistent
from weakref import WeakSet
import gc
import pkg_resources
......@@ -192,3 +193,35 @@ def _zmajor():
# zmajor is set to major ZODB version.
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