sapling/hg

48 lines
1.4 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env python
#
2006-02-06 07:21:02 +03:00
# mercurial - scalable distributed SCM
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
2010-01-20 07:20:08 +03:00
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import os
import sys
if os.environ.get('HGUNICODEPEDANTRY', False):
try:
reload(sys)
sys.setdefaultencoding("undefined")
except NameError:
pass
libdir = '@LIBDIR@'
if libdir != '@' 'LIBDIR' '@':
if not os.path.isabs(libdir):
libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
libdir)
libdir = os.path.abspath(libdir)
sys.path.insert(0, libdir)
chg: use a separate entry point Summary: Motivated by recent D7784903 which kills chg because it holds blackbox.log file descriptor, and that patch is causing race conditions running with chg (chg's sock atomic rename might fail if the directory is deleted). There are other ways to solve the direct issue. This diff takes a more aggressive but much cleaner approach. Basically, the `hg serve` framework is too late for chg's usecase - the repo was already loaded, extension side-effects have been already done at that time - chg has to use workarounds to be compatible with that. Even with a best effort, it is still possible to have weird interactions with shared repo because how hg loads extensions. The new approach is to pre-import a list of bundled extensions but do not run their `uisetup`s. This solves a couple of hard problems: - Compatibility - `uisetup` runs per request. That behaves exactly as what an extension author expects. - Less memory usage - there is no `repo` object is loaded in memory. - Reduced process count - since extension config change does not require a new chg server, the count of server processes would decrease (ex. `--config extensions.blackbox=!` won't require a new chg server) - Not holding fd to edenfs, since neither blackbox nor repo is loaded. This makes it possible to remove the hacky killing chg logic in D7784903. The downside is performance, since extension loading, and `uisetup` will run every time. Benchmark shows that's could be 50ms-ish. But we could move forward by moving extension logic to core incrementally to get rid of that cost too. This is basically a simplified version of my previous stack starting with [1]. The original commit message was: 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 [1]: https://bitbucket.org/quark-zju/hg-draft/commits/6f91a1a69fccf89ae6cbffc31da92889aa521f43 Reviewed By: singhsrb Differential Revision: D7840237 fbshipit-source-id: e3d613b41fe4b721238b86c5bf84434d32cf0609
2018-05-09 02:58:40 +03:00
if (sys.argv[1:5] == ['serve', '--cmdserver', 'chgunix', '--address']
and sys.argv[6:8] == ['--daemon-postexec', 'chdir:/']
and 'CHGINTERNALMARK' in os.environ):
# Shortcut path for chg server
from mercurial import dispatch
dispatch.runchgserver()
else:
# Non-chg path
try:
if sys.version_info[0] < 3 or sys.version_info >= (3, 6):
import hgdemandimport; hgdemandimport.enable()
except ImportError:
sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
' '.join(sys.path))
sys.stderr.write("(check your install and PYTHONPATH)\n")
sys.exit(-1)
from mercurial import dispatch
dispatch.run()