Patchwork [3,of,8] caches: introduce a function to warm cache

mail settings
Submitter Pierre-Yves David
Date May 2, 2017, 11:43 p.m.
Message ID <>
Download mbox | patch
Permalink /patch/20365/
State Accepted
Headers show


Pierre-Yves David - May 2, 2017, 11:43 p.m.
# HG changeset patch
# User Pierre-Yves David <>
# Date 1493753983 -7200
#      Tue May 02 21:39:43 2017 +0200
# Branch stable
# Node ID a98df6dbb264bd89889cd43f04bc6ddf6f9df142
# Parent  76a035851a620dcf36a6dd18a37409dff43c6d42
# EXP-Topic obscache
# Available At
#              hg pull -r a98df6dbb264
caches: introduce a function to warm cache

We have multiple caches that gain from being kept up to date. For example in a
server setup, we want to make sure the branchcache cache is hot for other
read-only clients.

Right now each cache tries to update themself in place where new data have been
added. However the approach is error prone (we might miss some spot) and
fragile. When nested transaction are involved, such cache updates might happen
before a top level transaction is committed. Writing caches for uncommitted
data on disk.

Having a single entry point, run at the end of each successful transaction,
helps to ensure the cache is up to date and refreshed at the right time.

We start with updating the branchmap cache but other will come.


diff --git a/mercurial/ b/mercurial/
--- a/mercurial/
+++ b/mercurial/
@@ -1121,6 +1121,10 @@  class localrepository(object):
         tr.addfinalize('txnclose-hook', txnclosehook)
+        def warmscache(tr2):
+            repo = reporef()
+            repo.updatecaches(tr2)
+        tr.addpostclose('warms-cache', warmscache)
         def txnaborthook(tr2):
             """To be run if transaction is aborted
@@ -1255,6 +1259,17 @@  class localrepository(object):
         return 0
+    @unfilteredmethod
+    def updatecaches(self, tr):
+        """warm appropriate caches after a transaction closed"""
+        if tr.hookargs.get('source') == 'strip':
+            # During strip, many caches are invalid but
+            # later call to `destroyed` will refresh them.
+            return
+        if tr.changes['revs']:
+            branchmap.updatecache(self.filtered('served'))
     def invalidatecaches(self):
         if '_tagscache' in vars(self):