[PATCH 3 of 7] transaction: add onclose hook for pre-close logic

Gregory Szorc gregory.szorc at gmail.com
Tue Mar 25 20:53:13 CDT 2014


On 3/24/14, 7:33 PM, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham at fb.com>
> # Date 1395701867 25200
> #      Mon Mar 24 15:57:47 2014 -0700
> # Node ID c84f51f8f92e0a3db4888ac9739f43fd866cac20
> # Parent  08595987c5b0e8af5aa8fec4debd7260f5a79e8f
> transaction: add onclose hook for pre-close logic
>
> Adds an optional onclose parameter to transactions that gets called just before
> the transaction is committed. This allows things that build up data over the
> course of the transaction (like the fncache) to commit their data.
>
> diff --git a/mercurial/transaction.py b/mercurial/transaction.py
> --- a/mercurial/transaction.py
> +++ b/mercurial/transaction.py
> @@ -42,12 +42,14 @@
>       opener.unlink(journal)
>
>   class transaction(object):
> -    def __init__(self, report, opener, journal, after=None, createmode=None):
> +    def __init__(self, report, opener, journal, after=None, createmode=None,
> +            onclose=None):
>           self.count = 1
>           self.usages = 1
>           self.report = report
>           self.opener = opener
>           self.after = after
> +        self.onclose = onclose
>           self.entries = []
>           self.map = {}
>           self.journal = journal
> @@ -126,6 +128,9 @@
>       @active
>       def close(self):
>           '''commit the transaction'''
> +        if self.count == 1 and self.onclose:
> +            self.onclose()
> +
>           self.count -= 1
>           if self.count != 0:
>               return

I don't mean to scope bloat this patch, but appending extra operations 
to transaction semantics is very appealing to me. We (Mozilla) have some 
extensions performing SQL against a local SQLite database, for example 
and would like the SQL to execute in a transaction tied to the Mercurial 
transaction.

I was wondering if a wrappable function is the best solution here. Given 
we're dealing with transactions and atomicity is hard, I don't believe 
wrapping functions is the most robust solution. For example, what 
happens when onclose() is wrapped multiple times and there is an 
exception in function 3 of 5? Will the commits of functions 1 and 2 have 
the opportunity to be rewound? (No they won't.)

I was curious if you'll consider a patch that makes things a bit more 
robust by adding a "transaction operation" API that allows custom 
objects to be registered to a transaction. They would have methods like 
"commit," "abort," and "rollback" that would be called during 
corresponding transaction events.


More information about the Mercurial-devel mailing list