changeset 32263:604d65e2c0b2

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.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Tue, 02 May 2017 21:39:43 +0200
parents 85ef5a073114
children a72caf0af38e
files mercurial/localrepo.py
diffstat 1 files changed, 15 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/localrepo.py	Tue May 02 18:45:51 2017 +0200
+++ b/mercurial/localrepo.py	Tue May 02 21:39:43 2017 +0200
@@ -1093,6 +1093,10 @@
                                **pycompat.strkwargs(hookargs))
             reporef()._afterlock(hook)
         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
             """
@@ -1227,6 +1231,17 @@
         self.destroyed()
         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):