# HG changeset patch # User Gregory Szorc # Date 2015-01-07 05:56:33 # Node ID d486e52352e80426db6f3d738e35bb675b3c3fa2 # Parent 7ad155e13f0f51df8e986a0ec4e58ac9a0ccedbb 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. diff --git a/mercurial/transaction.py b/mercurial/transaction.py --- a/mercurial/transaction.py +++ b/mercurial/transaction.py @@ -136,6 +136,8 @@ class transaction(object): 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 @@ class transaction(object): 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 @@ class transaction(object): 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"))