transaction: support for callbacks during abort
Previous transaction work added callbacks to be called during regular
transaction commit/close. As part of refactoring Mozilla's pushlog
extension (an extension that opens a SQLite database and tries to tie
its transaction semantics to Mercurial's transaction), I discovered that
the new transaction APIs were insufficient to avoid monkeypatching
transaction instance internals. Adding a callback that is called during
transaction abort removes the necessity for monkeypatching and completes
the API.
--- a/mercurial/transaction.py Mon Dec 15 14:11:19 2014 -0800
+++ b/mercurial/transaction.py Tue Jan 06 21:56:33 2015 -0800
@@ -136,6 +136,8 @@
self._finalizecallback = {}
# hold callback for post transaction close
self._postclosecallback = {}
+ # holds callbacks to call during abort
+ self._abortcallback = {}
def __del__(self):
if self.journal:
@@ -361,6 +363,17 @@
self._postclosecallback[category] = callback
@active
+ def addabort(self, category, callback):
+ """add a callback to be called when the transaction is aborted.
+
+ The transaction will be given as the first argument to the callback.
+
+ Category is a unique identifier to allow overwriting an old callback
+ with a newer callback.
+ """
+ self._abortcallback[category] = callback
+
+ @active
def close(self):
'''commit the transaction'''
if self.count == 1:
@@ -443,6 +456,8 @@
self.report(_("transaction abort!\n"))
try:
+ for cat in sorted(self._abortcallback):
+ self._abortcallback[cat](self)
_playback(self.journal, self.report, self.opener, self._vfsmap,
self.entries, self._backupentries, False)
self.report(_("rollback completed\n"))