Commit 64d1f40b authored by Kirill Smelkov's avatar Kirill Smelkov

bigfile/zodb: Monkey-patch for ZODB.Connection to support callback on .open()

ZODB.Connection has support for calling callbacks on .close() but not on
.open() . We'll need to hook into both Connection open/close process in the
next patch (for _ZBigFileH to stay in sync with Connection state).

NOTE

on-open  callbacks are setup once and fire many times on every open,
on-close callbacks are setup once and fire only once on next close.

The reason for this is that on-close callbacks are useful for scheduling
current connection cleanup, after its processing is done. But on-open
callback is for future connection usage, which is generally not related
to current connection.

/cc @jm, @vpelletier
parent b92f82c8
...@@ -35,6 +35,7 @@ from transaction.interfaces import IDataManager, ISynchronizer ...@@ -35,6 +35,7 @@ from transaction.interfaces import IDataManager, ISynchronizer
from persistent import Persistent, PickleCache from persistent import Persistent, PickleCache
from BTrees.LOBTree import LOBTree from BTrees.LOBTree import LOBTree
from zope.interface import implementer from zope.interface import implementer
from ZODB.Connection import Connection
# TODO document that first data access must be either after commit or Connection.add # TODO document that first data access must be either after commit or Connection.add
...@@ -227,6 +228,33 @@ class ZBigFile(LivePersistent): ...@@ -227,6 +228,33 @@ class ZBigFile(LivePersistent):
# patch for ZODB.Connection to support callback on .open()
# NOTE on-open callbacks are setup once and fire many times on every open
# on-close callbacks are setup once and fire only once on next close
Connection._onOpenCallbacks = None
def Connection_onOpenCallback(self, f):
if self._onOpenCallbacks is None:
# NOTE WeakSet does not work for bound methods - the are always create
# anew for each obj.method access, and thus will go away almost immediately
self._onOpenCallbacks = set()
self._onOpenCallbacks.add(f)
assert not hasattr(Connection, 'onOpenCallback')
Connection.onOpenCallback = Connection_onOpenCallback
orig_Connection_open = Connection.open
def Connection_open(self, transaction_manager=None, delegate=True):
orig_Connection_open(self, transaction_manager, delegate)
if self._onOpenCallbacks:
for f in self._onOpenCallbacks:
f()
Connection.open = Connection_open
# ------------
# BigFileH wrapper that also acts as DataManager proxying changes back to ZODB # BigFileH wrapper that also acts as DataManager proxying changes back to ZODB
# objects at two-phase-commit (TPC) level. # objects at two-phase-commit (TPC) level.
# #
......
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