[PATCH 3 of 7] transaction: add onclose hook for pre-close logic
Gregory Szorc
gregory.szorc at gmail.com
Tue Mar 25 22:02:55 CDT 2014
On 3/25/14, 7:19 PM, Durham Goode wrote:
> On 3/25/14 6:53 PM, "Gregory Szorc" <gregory.szorc at gmail.com> wrote:
>
>> 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.
>
> As a first step, I could add an onabort handler to transactions that's
> called at the beginning of an abort. That would give extensions a way to
> hook in to the abort phase (so functions 1 and 2 could rollback).
>
> I'd rather not add a full transaction extensibility framework to this
> patch, mainly because of the amount of design involved. (How do you
> register? Statically at uisetup time? Dynamically as the transactions are
> being passed around? How do you serialize information to make hg recover
> work? Assume the extension will handle that bit?) And my need to get
> this series in by the end of the week.
I think onabort would suffice for the near term. A robust solution can
come later, if it's needed.
More information about the Mercurial-devel
mailing list