Commit ceadfcc7 authored by Kirill Smelkov's avatar Kirill Smelkov

lib/zodb: Teach Connection.onResyncCallback to work on ZODB4

In 959ae2d0 (lib/zodb: Add patch to ZODB.Connection to support callback
on connection DB view change) we added patch for ZODB.Connection to
support callback when database view of the connection changes. At that
time the patch was working for ZODB5 and ZODB4 was TODO.
Let's add support for ZODB4 (both ZODB4 and ZODB4-wc2) now.

As a reminder: ZBigFile + WCFS client integration will use this callback
to keep WCFS connection in sync with ZODB connection.

Preliminary history:

533a4cfa     X onResyncCallback for ZODB4
parent 23362204
......@@ -312,7 +312,6 @@ def test_zconn_at():
# verify that ZODB.Connection.onResyncCallback works
@xfail(zmajor < 5, reason="ZODB.Connection.onResyncCallback is TODO for ZODB4")
@func
def test_zodb_onresync():
stor = testdb.getZODBStorage()
......
......@@ -243,8 +243,6 @@ ZODB.Connection.Connection._onResyncCallbacks = None
def Connection_onResyncCallback(self, f):
if zmajor <= 3:
raise AssertionError("onResyncCallback: ZODB3 is not supported anymore")
if zmajor == 4:
raise AssertionError("onResyncCallback: TODO: add support for ZODB4")
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
......@@ -254,25 +252,43 @@ def Connection_onResyncCallback(self, f):
assert not hasattr(ZODB.Connection.Connection, 'onResyncCallback')
ZODB.Connection.Connection.onResyncCallback = Connection_onResyncCallback
def Connection__callResyncCallbacks(self):
# 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()
assert not hasattr(ZODB.Connection.Connection, '_callResyncCallbacks')
ZODB.Connection.Connection._callResyncCallbacks = Connection__callResyncCallbacks
# ZODB5: hook into Connection.newTransaction
if zmajor >= 5:
_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()
self._callResyncCallbacks()
ZODB.Connection.Connection.newTransaction = _ZConnection_newTransaction
# ZODB4: hook into Connection._storage_sync
# ZODB4: hook into Connection._flush_invalidations and ._resetCache
elif zmajor == 4:
pass # raises in onResyncCallback
# ._flush_invalidations is called by both Connection.open and Connection._storage_sync
# however Connection.open might call ._resetCache instead if global reset is requested
_orig_Connection__flush_invalidations = ZODB.Connection.Connection._flush_invalidations
_orig_Connection__resetCache = ZODB.Connection.Connection._resetCache
def _ZConnection__flush_invalidations(self):
_orig_Connection__flush_invalidations(self)
self._callResyncCallbacks()
def _ZConnection__resetCache(self):
_orig_Connection__resetCache(self)
self._callResyncCallbacks()
ZODB.Connection.Connection._flush_invalidations = _ZConnection__flush_invalidations
ZODB.Connection.Connection._resetCache = _ZConnection__resetCache
# ZODB3
......
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