[PATCH 1 of 8] cache: make the cache updated callback easily accessible to extension
Gregory Szorc
gregory.szorc at gmail.com
Sat May 20 13:38:59 EDT 2017
On Sat, May 20, 2017 at 7:21 AM, Pierre-Yves David <
pierre-yves.david at ens-lyon.org> wrote:
>
>
> On 05/20/2017 06:49 AM, Yuya Nishihara wrote:
>
>> On Fri, 19 May 2017 16:28:00 +0200, Pierre-Yves David wrote:
>>
>>> # HG changeset patch
>>> # User Pierre-Yves David <pierre-yves.david at octobus.net>
>>> # Date 1495192163 -7200
>>> # Fri May 19 13:09:23 2017 +0200
>>> # Node ID 1fe18fcc122b4d8e14264a3670d2d5f99f11bd75
>>> # Parent 8a87bfc5bebbbe0ac996ac8e047a029eb931af45
>>> # EXP-Topic obscache
>>> # Available At https://www.mercurial-scm.org/
>>> repo/users/marmoute/mercurial/
>>> # hg pull https://www.mercurial-scm.org/
>>> repo/users/marmoute/mercurial/ -r 1fe18fcc122b
>>> cache: make the cache updated callback easily accessible to extension
>>>
>>> This will help extension to benefit from this new logic. As a side
>>> effect this
>>> clarify the 'transaction' method a little bit.
>>>
>>> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
>>> --- a/mercurial/localrepo.py
>>> +++ b/mercurial/localrepo.py
>>> @@ -1091,10 +1091,7 @@ class localrepository(object):
>>> **pycompat.strkwargs(hookargs))
>>> reporef()._afterlock(hook)
>>> tr.addfinalize('txnclose-hook', txnclosehook)
>>> - def warmscache(tr2):
>>> - repo = reporef()
>>> - repo.updatecaches(tr2)
>>> - tr.addpostclose('warms-cache', warmscache)
>>> + tr.addpostclose('warms-cache', self._buildcacheupdater(tr))
>>> def txnaborthook(tr2):
>>> """To be run if transaction is aborted
>>> """
>>> @@ -1229,6 +1226,20 @@ class localrepository(object):
>>> self.destroyed()
>>> return 0
>>>
>>> + def _buildcacheupdater(self, newtransaction):
>>> + """called during transaction to build the callback updating
>>> cache
>>> +
>>> + Lives on the repository to help extension who might want to
>>> augment
>>> + this logic. For this purpose, the created transaction is passed
>>> to the
>>> + method.
>>> + """
>>> + # we must avoid cyclic reference between repo and transaction.
>>> + reporef = weakref.ref(self)
>>> + def updater(tr):
>>> + repo = reporef()
>>> + repo.updatecaches(tr)
>>> + return updater
>>>
>>
>> Out of curiosity, why do we need this whole weakref business? IIUC, repo
>> holds
>> no strong reference to the transaction object.
>>
>
> I've preserved the usage of the reporef from the 'transaction' method.
>
> Tracking the introduction of the 'reporef' there trace back to
> db8679812f84 and usage of repository in "afterlock" call.
>
> So I'm not sure it is useful in this context but it probably do not hurt.
I believe I inserted some of these. There are circular references involving
repo instances. The ref arc is inserted through transactions, specifically
these transaction callbacks, which either store a ref to the repo
explicitly (as in this patch) or inherit one via the outer scope.
If a single repo undergoes multiple transactions, we effectively leak
transactions, repoviews, and associated objects because of the circular
refs. I believe we still have leaks today because I have a handful of old
patches sitting around attempting to break some cycles by inserting more
weakrefs and proxies. If you want to reproduce, run `hg convert` on a large
repo.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.mercurial-scm.org/pipermail/mercurial-devel/attachments/20170520/fca35cf8/attachment.html>
More information about the Mercurial-devel
mailing list