*** ./lib/python/Products/MailHost/MailHost.py.orig 2007-02-01 15:49:31.000000000 -0600
--- ./lib/python/Products/MailHost/MailHost.py 2007-02-01 15:52:15.000000000 -0600
***************
*** 157,162 ****
--- 157,170 ----
security.declarePrivate('_send')
def _send( self, mfrom, mto, messageText ):
+ T = get_transaction()
+ if hasattr(T,'afterCommitHook'):
+ T.afterCommitHook(getattr(self,'_really_send'), mfrom, mto, messageText)
+ else:
+ return self._really_send(mfrom, mto, messageText)
+
+ security.declarePrivate('_really_send')
+ def _really_send( self, mfrom, mto, messageText ):
""" Send the message """
smtpserver = SMTP(self.smtp_host, int(self.smtp_port) )
if self.smtp_uid:
*** ./lib/python/transaction/_transaction.py.orig 2007-01-31 16:39:59.000000000 -0600
--- ./lib/python/transaction/_transaction.py 2007-02-01 10:22:53.000000000 -0600
***************
*** 115,120 ****
--- 115,131 ----
passing it a callable and arguments. The callable will be called with its
arguments at the start of the commit (but not for substransaction commits).
+ After-commit hook
+ ---------------
+
+ Sometimes, applications want to take some action not related to the
+ ZODB, if the ZODB transaction commits okay. For example, you might
+ want to send an email, but not if the transaction doesn't commit. A
+ post-commit hook is available for such use cases, just use afterCommitHook()
+ passing it a callable and arguments. The callable will be called with its
+ arguments after the commit completes.
+
+
Error handling
--------------
***************
*** 238,247 ****
# raised, incorporating this traceback.
self._failure_traceback = None
! # Holds (hook, args, kws) triples added by beforeCommitHook.
# TODO: in Python 2.4, change to collections.deque; lists can be
# inefficient for FIFO access of this kind.
self._before_commit = []
# Raise TransactionFailedError, due to commit()/join()/register()
# getting called when the current transaction has already suffered
--- 249,259 ----
# raised, incorporating this traceback.
self._failure_traceback = None
! # Holds (hook, args, kws) triples added by before/afterCommitHook.
# TODO: in Python 2.4, change to collections.deque; lists can be
# inefficient for FIFO access of this kind.
self._before_commit = []
+ self._after_commit = []
# Raise TransactionFailedError, due to commit()/join()/register()
# getting called when the current transaction has already suffered
***************
*** 384,389 ****
--- 396,404 ----
if self._manager:
self._manager.free(self)
self._synchronizers.map(lambda s: s.afterCompletion(self))
+
+ self._callAfterCommitHooks()
+
self.log.debug("commit")
def _saveCommitishError(self):
***************
*** 412,417 ****
--- 427,445 ----
hook, args, kws = self._before_commit.pop(0)
hook(*args, **kws)
+ def getAfterCommitHooks(self):
+ return iter(self._after_commit)
+
+ def afterCommitHook(self, hook, *args, **kws):
+ self._after_commit.append((hook, args, kws))
+
+ def _callAfterCommitHooks(self):
+ # Call all hooks registered, allowing further registrations
+ # during processing.
+ while self._after_commit:
+ hook, args, kws = self._after_commit.pop(0)
+ hook(*args, **kws)
+
def _commitResources(self):
# Execute the two-phase commit protocol.