Commit 54656f3d authored by Jeremy Hylton's avatar Jeremy Hylton

Cleanup of callback handling and tpc_vote().

There are two kinds of callbacks, commit actions and close actions.
It is assumed that the use of these callbacks is infrequent.  As a
result, the implementation used tuples defined as class attributes to
avoid creation of instance variables to hold callbacks in the common
case.  This implementation is complicated because tuples are
immutable.  Unfortunately, the instance variables were actually
created anyway in tpc_abort() and tpc_vote().

This implementation changes the class attributes __onCloseCallbacks
and __onCommitCallbacks to default to None.  If a callback is
registered with an instance, a list is bound to an instance attribute
of the same name.  When the transaction commits or aborts, the
instance attribute is deleted.

tpc_vote(): Remove the default arguments since they are unused in the
body of the method.
parent 6665dd6a
...@@ -84,8 +84,8 @@ ...@@ -84,8 +84,8 @@
############################################################################## ##############################################################################
"""Database connection support """Database connection support
$Id: Connection.py,v 1.54 2001/05/21 22:45:38 jeremy Exp $""" $Id: Connection.py,v 1.55 2001/05/22 20:57:03 jeremy Exp $"""
__version__='$Revision: 1.54 $'[11:-2] __version__='$Revision: 1.55 $'[11:-2]
from cPickleCache import PickleCache from cPickleCache import PickleCache
from POSException import ConflictError, ExportError from POSException import ConflictError, ExportError
...@@ -267,39 +267,44 @@ class Connection(ExportImport.ExportImport): ...@@ -267,39 +267,44 @@ class Connection(ExportImport.ExportImport):
def cacheFullSweep(self, dt=0): self._cache.full_sweep(dt) def cacheFullSweep(self, dt=0): self._cache.full_sweep(dt)
def cacheMinimize(self, dt=0): self._cache.minimize(dt) def cacheMinimize(self, dt=0): self._cache.minimize(dt)
__onCloseCallbacks=() __onCloseCallbacks = None
def onCloseCallback(self, f): def onCloseCallback(self, f):
self.__onCloseCallbacks=self.__onCloseCallbacks+(f,) if self.__onCloseCallbacks is None:
self.__onCloseCallbacks = []
self.__onCloseCallbacks.append(f)
def close(self): def close(self):
self._incrgc() # This is a good time to do some GC self._incrgc() # This is a good time to do some GC
db=self._db db=self._db
# Call the close callbacks. # Call the close callbacks.
for f in self.__onCloseCallbacks: if self.__onCloseCallbacks is not None:
try: f() for f in self.__onCloseCallbacks:
except: try: f()
f=getattr(f, 'im_self', f) except:
LOG('ZODB',ERROR, 'Close callback failed for %s' % f, f=getattr(f, 'im_self', f)
error=sys.exc_info()) LOG('ZODB',ERROR, 'Close callback failed for %s' % f,
self.__onCloseCallbacks=() error=sys.exc_info())
self.__onCloseCallbacks = None
self._db=self._storage=self._tmp=self.new_oid=self._opened=None self._db=self._storage=self._tmp=self.new_oid=self._opened=None
self._debug_info=() self._debug_info=()
# Return the connection to the pool. # Return the connection to the pool.
db._closeConnection(self) db._closeConnection(self)
__onCommitActions=() __onCommitActions = None
def onCommitAction(self, method_name, *args, **kw): def onCommitAction(self, method_name, *args, **kw):
self.__onCommitActions = self.__onCommitActions + ( if self.__onCommitActions is None:
(method_name, args, kw),) self.__onCommitActions = []
self.__onCommitActions.append((method_name, args, kw))
get_transaction().register(self) get_transaction().register(self)
def commit(self, object, transaction, _type=type, _st=type('')): def commit(self, object, transaction, _type=type, _st=type('')):
if object is self: if object is self:
# We registered ourself. Execute a commit action, if any. # We registered ourself. Execute a commit action, if any.
if self.__onCommitActions: if self.__onCommitActions is not None:
method_name, args, kw = self.__onCommitActions[0] method_name, args, kw = self.__onCommitActions.pop(0)
self.__onCommitActions = self.__onCommitActions[1:]
apply(getattr(self, method_name), (transaction,) + args, kw) apply(getattr(self, method_name), (transaction,) + args, kw)
return return
oid=object._p_oid oid=object._p_oid
...@@ -605,7 +610,8 @@ class Connection(ExportImport.ExportImport): ...@@ -605,7 +610,8 @@ class Connection(ExportImport.ExportImport):
raise raise
def tpc_abort(self, transaction): def tpc_abort(self, transaction):
self.__onCommitActions = () if self.__onCommitAction is not None:
del self.__onCommitActions
self._storage.tpc_abort(transaction) self._storage.tpc_abort(transaction)
cache=self._cache cache=self._cache
cache.invalidate(self._invalidated) cache.invalidate(self._invalidated)
...@@ -629,12 +635,14 @@ class Connection(ExportImport.ExportImport): ...@@ -629,12 +635,14 @@ class Connection(ExportImport.ExportImport):
self._storage.tpc_begin(transaction) self._storage.tpc_begin(transaction)
def tpc_vote(self, transaction, def tpc_vote(self, transaction):
_type=type, _st=type('')): if self.__onCommitActions is not None:
self.__onCommitActions = () del self.__onCommitActions
try: vote=self._storage.tpc_vote try:
except: return vote=self._storage.tpc_vote
s=vote(transaction) except AttributeError:
return
s = vote(transaction)
self._handle_serial(s) self._handle_serial(s)
def _handle_serial(self, store_return, oid=None, change=1): def _handle_serial(self, store_return, oid=None, change=1):
......
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