[PATCH] transaction: support for callbacks during abort

Gregory Szorc gregory.szorc at gmail.com
Sat Jul 11 13:06:57 CDT 2015


On Sat, Jul 11, 2015 at 3:31 AM, FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
wrote:

> At Tue, 06 Jan 2015 22:00:18 -0800,
> Gregory Szorc wrote:
> >
> > # 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
>
> (snip)
>
> > @@ -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:
>
> (also CC-ed to Pierre-Yves as a implementer of 'txnabort' hook)
>
> Now, I'm working for dirstate consistency around inside and border of
> transaction, and planning to use this abort callback mechanism to know
> the end of transaction at failure.
>
> But current implementation doesn't invoke abort callbacks, if there is
> no change on repository data at aborting transaction: e.g. "hg import"
> fails to import the first patch.
>
> So, there is no easy and certain way to know the end of transaction at
> failure.
>
> BTW, this also causes that 'txnabort' hook isn't invoked at aborting
> transaction in such case, because 'txnabort' hook invocation is
> achieved by abort callback mechanism. This may need some cleanup for
> orphan 'pretxnopen' hook assuming that one of 'txnclose' or 'txnabort'
> will be invoked subsequently.
>
> Then, please let me confirm some points below before changing around
> 'transaction._abort()' for my purpose:
>
>   - are there any usecases to expect actual changes to be rollbacked ?
>
>     In other words, does it cause problem to invoke abort callbacks
>     regardless of actual changes ?
>

Mozilla has a use case in our pushlog extension (
https://hg.mozilla.org/hgcustom/version-control-tools/file/45f5a094da62/hgext/pushlog/__init__.py#l221).
Not sure if there is anything in core. Possibly not.


>
>   - are there any usecases to refer changes to be rollbacked in abort
>     callbacks ?
>
>     In other words, does it cause problem to invoke abort callbacks
>     after rollbacking ?
>

I don't think it matters if registered rollbacks are called before or after
core rollbacks. But, I think it is important that the "rollback completed"
message is printed after all rollbacks are performed. Otherwise, you could
see weird output. e.g.

  adding changesets
  adding manifests
  adding file changes
  added 1 changesets with 1 changes to 1 files
  transaction abort!
  rollback completed
  rolling back message from extension


>     BTW, 'txnabort' hooks are invoked without 'pending', and it means
>     that such changes should be invisible to 'txnabort' hooks, doesn't
>     it ? > Pierre-Yves
>
>     Then, IMHO, such changes should be invisible to abort callbacks,
>     too.
>
> Maybe, should I introduce another callback to know the end of
> transaction (regardless of the result of it, or only at failure) ?
>

I think that would be a nice addition to the API and would round out the
callback support nicely. This could be used for better forensic logging,
for example.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20150711/7bc0be45/attachment.html>


More information about the Mercurial-devel mailing list