[PATCH] transaction: support for callbacks during abort
Gregory Szorc
gregory.szorc at gmail.com
Wed Jan 7 06:00:18 UTC 2015
# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1420610193 28800
# Tue Jan 06 21:56:33 2015 -0800
# Node ID 5affbb31eea2a1034bc73ee20182880adcc9af36
# Parent b9d06fa10ef29c012d48bd4f3c93fd7bf1347d40
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
@@ -135,8 +135,10 @@ class transaction(object):
# holds callback to call when writing the transaction
self._finalizecallback = {}
# hold callback for post transaction close
self._postclosecallback = {}
+ # holds callbacks to call during abort
+ self._abortcallback = {}
def __del__(self):
if self.journal:
self._abort()
@@ -360,8 +362,19 @@ 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:
self._generatefiles()
@@ -442,8 +455,10 @@ 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"))
except Exception:
More information about the Mercurial-devel
mailing list