[PATCH 1 of 3 RFC] chg: add a standalone entry point
Jun Wu
quark at fb.com
Mon Oct 3 06:11:18 UTC 2016
# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1475458616 -3600
# Mon Oct 03 02:36:56 2016 +0100
# Node ID 7b19924c9fd57fbb7fa39c103902d51d7ea9beb4
# Parent cd7276f7ea8308df2c5d8874d335d73247d0f357
# Available At https://bitbucket.org/quark-zju/hg-draft
# hg pull https://bitbucket.org/quark-zju/hg-draft -r 7b19924c9fd5
chg: add a standalone entry point
This is the beginning of a series that does a re-architect to chg mentioned
in [1], to achieve better compatibility.
The compatibility issues are mainly around "uisetup"s and "reposetup"s:
- Developers are usually unaware that uisetup runs only once per chg
process. We cannot reliably devel-warn them. The result is, potential
broken code are written. For example, it's really hard for chg to deal
with "experimental.evolution" changed from unset to manually set in
config files because setconfig is used if that config option is not set.
- An unnecessary "reposetup" caused by "hg serve" may have unwanted
side effects. This can become troublesome if the repo requires things
like remotefilelog or lz4revlog, and the user sets HGRCPATH to run
tests.
The current chg implementation assumes that "loading" an extension is not
side effect free - if extension related config has changed, a restart is
needed. The new idea is, "loading" = "importing" + "run ui/extsetup", the
"importing" part can be side-effect free for some extensions. And benchmark
shows "import" takes most of the time consumed, while "uisetup" is usually
very fast. We can afford running "uisetup"s per request.
To be able to (pre-)"import" extensions without running any "uisetup"s, a
different entry point is needed. Otherwise as long as we go through the
normal dispatch / runcommand ("hg serve") flow, "uisetup"s cannot be
avoided.
Aside from better compatibility, we can also remove some hacks:
- chg client: no longer needs to extract sensitive argv
- chg server: confighash can be changed to only hash environment variables
(reduce the number of server processes)
- chg server: srcui.walkconfig hack is no longer necessary
This patch adds a new script "chgserve" as the new entry point. Currently,
it is just a minimal implementation that makes "CHGHG=chgserve chg ..."
work, without doing any pre-importing. The change could also be done in the
"hg" script. But since chg is still experimental, let's keep "hg" untouched
for now.
[1]: www.mercurial-scm.org/pipermail/mercurial-devel/2016-July/085965.html
diff --git a/contrib/chg/chgserve b/contrib/chg/chgserve
new file mode 100755
--- /dev/null
+++ b/contrib/chg/chgserve
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+from __future__ import absolute_import
+
+import os
+import sys
+
+from mercurial import (
+ cmdutil,
+ commands,
+ commandserver,
+ dispatch,
+ fancyopts,
+ ui as uimod,
+ util,
+)
+
+from hgext import chgserver
+
+def _confighash(ui):
+ envitems = [(k, v) for k, v in os.environ.iteritems()
+ if chgserver._envre.match(k)]
+ envhash = chgserver._hashlist(sorted(envitems))
+ return envhash[:12]
+
+def _startchgservice():
+ # patch chgserver's confighash to only hash environment variables
+ chgserver._confighash = _confighash
+
+ ui = uimod.ui()
+ repo = None
+ args = sys.argv[2:]
+ dispatch._earlygetopt(['--config'], args)
+ opts = {}
+ fancyopts.fancyopts(args, commands.table['^serve'][1], opts)
+
+ service = chgserver.chgunixservice(ui, repo, opts)
+ cmdutil.service(opts, initfn=service.init, runfn=service.run)
+
+def _setbinary():
+ for fp in (sys.stdin, sys.stdout, sys.stderr):
+ util.setbinary(fp)
+
+if __name__ == '__main__':
+ _setbinary()
+ sys.exit(_startchgservice())
More information about the Mercurial-devel
mailing list