[PATCH 3 of 4 V2] chgcache: implement the background preloading thread

Jun Wu quark at fb.com
Wed Feb 22 21:16:10 EST 2017


# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1487813979 28800
#      Wed Feb 22 17:39:39 2017 -0800
# Node ID 28571825744fb4f4b424385f55afa9484532ef43
# Parent  630457e88fa0485bce7822345ea640b5cdcb9b8e
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 28571825744f
chgcache: implement the background preloading thread

The background preloading thread is meant to used by chg master, and it sets
up the IPC channel.

diff --git a/mercurial/chgcache.py b/mercurial/chgcache.py
--- a/mercurial/chgcache.py
+++ b/mercurial/chgcache.py
@@ -13,4 +13,5 @@ import select
 import socket
 import termios
+import threading
 import time
 
@@ -87,2 +88,51 @@ def reportrepopaths():
         for path in _localrepopaths:
             _ipc.send('%s %s' % (now, path))
+
+# -- only used by the master --------------------------------------------------
+
+def _initipc():
+    """initialize and return the global IPC object"""
+    global _ipc
+    if _ipc is None:
+        _ipc = socketipc()
+    return _ipc
+
+class preloader(object):
+    """background thread doing the actual preloading work"""
+
+    def __init__(self):
+        self._ipc = _initipc()
+        self._shouldexit = threading.Event()
+        self._thread = None
+
+    def start(self):
+        if self._thread is not None:
+            self.stop()
+        self._thread = threading.Thread(target=self._preloadloop,
+                                        name='chgcache.preloader')
+        self._thread.daemon = True
+        self._thread.start()
+
+    def stop(self):
+        if self._thread is None:
+            return
+        self._shouldexit.set()
+        self._ipc.send('') # unblock (possibly blocking) recv()
+        self._thread.join()
+        self._thread = None
+
+    def _preloadloop(self, interval=0.5):
+        while not self._shouldexit.is_set():
+            try:
+                atimestr, path = self._ipc.recv().split(' ', 1)
+                atime = float(atimestr)
+            except Exception: # ignore errors
+                pass
+            else:
+                if path in _repocaches and _repocaches[path][0] >= atime:
+                    # this repocache is up-to-date, no need to update
+                    continue
+                now = time.time()
+                # TODO update repocache properly
+                repocache = None
+                _repocaches[path] = (now, repocache)


More information about the Mercurial-devel mailing list