annotate mercurial/commandserver.py @ 44477:ad718271a9eb

git: skeleton of a new extension to _directly_ operate on git repos This is based in part of work I did years ago in hgit, but it's mostly new code since I'm using pygit2 instead of dulwich and the hg storage interfaces have improved. Some cleanup of old hgit code by Pulkit, which I greatly appreciate. test-git-interop.t does not cover a whole lot of cases, but it passes. It includes status, diff, making a new commit, and `hg annotate` working on the git repository. This is _not_ (yet) production quality code: this is an experiment. Known technical debt lurking in this implementation: * Writing bookmarks just totally ignores transactions. * The way progress is threaded down into the gitstore is awful. * Ideally we'd find a way to incrementally reindex DAGs. I'm not sure how to do that efficiently, so we might need a "known only fast-forwards" mode on the DAG indexer for use on `hg commit` and friends. * We don't even _try_ to do anything reasonable for `hg pull` or `hg push`. * Mercurial need an interface for the changelog type. Tests currently require git 2.24 as far as I'm aware: `git status` has some changed output that I didn't try and handle in a compatible way. This patch has produced some interesting cleanups, most recently on the manifest type. I expect continuing down this road will produce other meritorious cleanups throughout our code. Differential Revision: https://phab.mercurial-scm.org/D6734
author Augie Fackler <augie@google.com>
date Tue, 11 Feb 2020 00:44:59 -0500
parents f5c006621f07
children d6e99a446eea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
1 # commandserver.py - communicate with Mercurial's API over a pipe
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
2 #
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
3 # Copyright Matt Mackall <mpm@selenic.com>
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
4 #
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
7
27351
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
8 from __future__ import absolute_import
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
9
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
10 import errno
29513
e5b4d79a9140 commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29512
diff changeset
11 import gc
27351
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
12 import os
29513
e5b4d79a9140 commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29512
diff changeset
13 import random
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
14 import signal
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
15 import socket
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
16 import struct
27351
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
17 import traceback
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
18
36940
b0ffcb540357 commandserver: prefer first-party selectors module from Python 3 to backport
Augie Fackler <augie@google.com>
parents: 36835
diff changeset
19 try:
b0ffcb540357 commandserver: prefer first-party selectors module from Python 3 to backport
Augie Fackler <augie@google.com>
parents: 36835
diff changeset
20 import selectors
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
21
36940
b0ffcb540357 commandserver: prefer first-party selectors module from Python 3 to backport
Augie Fackler <augie@google.com>
parents: 36835
diff changeset
22 selectors.BaseSelector
b0ffcb540357 commandserver: prefer first-party selectors module from Python 3 to backport
Augie Fackler <augie@google.com>
parents: 36835
diff changeset
23 except ImportError:
b0ffcb540357 commandserver: prefer first-party selectors module from Python 3 to backport
Augie Fackler <augie@google.com>
parents: 36835
diff changeset
24 from .thirdparty import selectors2 as selectors
b0ffcb540357 commandserver: prefer first-party selectors module from Python 3 to backport
Augie Fackler <augie@google.com>
parents: 36835
diff changeset
25
27351
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
26 from .i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
27 from .pycompat import getattr
27351
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
28 from . import (
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
29 encoding,
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
30 error,
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
31 loggingutil,
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
32 pycompat,
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
33 repocache,
27351
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
34 util,
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
35 vfs as vfsmod,
27351
28e50c4b15ed commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 26587
diff changeset
36 )
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36940
diff changeset
37 from .utils import (
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
38 cborutil,
37119
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36940
diff changeset
39 procutil,
d4a2e0d5d042 procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 36940
diff changeset
40 )
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
41
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
42
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
43 class channeledoutput(object):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
44 """
22561
1120b1e2f975 cmdserver: correct doc of channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents: 21195
diff changeset
45 Write data to out in the following format:
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
46
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
47 data length (unsigned int),
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
48 data
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
49 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
50
22563
8cc5e673cac0 cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents: 22562
diff changeset
51 def __init__(self, out, channel):
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
52 self.out = out
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
53 self.channel = channel
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
54
27415
f4ca33e33781 commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents: 27352
diff changeset
55 @property
f4ca33e33781 commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents: 27352
diff changeset
56 def name(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
57 return b'<%c-channel>' % self.channel
27415
f4ca33e33781 commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents: 27352
diff changeset
58
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
59 def write(self, data):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
60 if not data:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
61 return
30263
7f2313450e86 cmdserver: write channel header and payload by a single write() call
Yuya Nishihara <yuya@tcha.org>
parents: 29609
diff changeset
62 # single write() to guarantee the same atomicity as the underlying file
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
63 self.out.write(struct.pack(b'>cI', self.channel, len(data)) + data)
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
64 self.out.flush()
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
65
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
66 def __getattr__(self, attr):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
67 if attr in ('isatty', 'fileno', 'tell', 'seek'):
18174
56ef99fbd6f2 commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents: 17425
diff changeset
68 raise AttributeError(attr)
22563
8cc5e673cac0 cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents: 22562
diff changeset
69 return getattr(self.out, attr)
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
70
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
71
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
72 class channeledmessage(object):
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
73 """
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
74 Write encoded message and metadata to out in the following format:
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
75
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
76 data length (unsigned int),
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
77 encoded message and metadata, as a flat key-value dict.
40590
83dd8c63a0c6 ui: extract helpers to write message with type or label
Yuya Nishihara <yuya@tcha.org>
parents: 40589
diff changeset
78
83dd8c63a0c6 ui: extract helpers to write message with type or label
Yuya Nishihara <yuya@tcha.org>
parents: 40589
diff changeset
79 Each message should have 'type' attribute. Messages of unknown type
83dd8c63a0c6 ui: extract helpers to write message with type or label
Yuya Nishihara <yuya@tcha.org>
parents: 40589
diff changeset
80 should be ignored.
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
81 """
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
82
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
83 # teach ui that write() can take **opts
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
84 structured = True
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
85
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
86 def __init__(self, out, channel, encodename, encodefn):
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
87 self._cout = channeledoutput(out, channel)
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
88 self.encoding = encodename
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
89 self._encodefn = encodefn
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
90
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
91 def write(self, data, **opts):
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
92 opts = pycompat.byteskwargs(opts)
40594
234c2d8c9e48 commandserver: send raw progress information to message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40590
diff changeset
93 if data is not None:
234c2d8c9e48 commandserver: send raw progress information to message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40590
diff changeset
94 opts[b'data'] = data
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
95 self._cout.write(self._encodefn(opts))
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
96
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
97 def __getattr__(self, attr):
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
98 return getattr(self._cout, attr)
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
99
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
100
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
101 class channeledinput(object):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
102 """
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
103 Read data from in_.
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
104
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
105 Requests for input are written to out in the following format:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
106 channel identifier - 'I' for plain input, 'L' line based (1 byte)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
107 how many bytes to send at most (unsigned int),
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
108
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
109 The client replies with:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
110 data length (unsigned int), 0 meaning EOF
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
111 data
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
112 """
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
113
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
114 maxchunksize = 4 * 1024
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
115
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
116 def __init__(self, in_, out, channel):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
117 self.in_ = in_
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
118 self.out = out
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
119 self.channel = channel
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
120
27415
f4ca33e33781 commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents: 27352
diff changeset
121 @property
f4ca33e33781 commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents: 27352
diff changeset
122 def name(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
123 return b'<%c-channel>' % self.channel
27415
f4ca33e33781 commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents: 27352
diff changeset
124
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
125 def read(self, size=-1):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
126 if size < 0:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
127 # if we need to consume all the clients input, ask for 4k chunks
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
128 # so the pipe doesn't fill up risking a deadlock
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
129 size = self.maxchunksize
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
130 s = self._read(size, self.channel)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
131 buf = s
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
132 while s:
14728
350dcd481410 cmdserver: fix read-loop string concatenation
Idan Kamara <idankk86@gmail.com>
parents: 14719
diff changeset
133 s = self._read(size, self.channel)
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
134 buf += s
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
135
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
136 return buf
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
137 else:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
138 return self._read(size, self.channel)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
139
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
140 def _read(self, size, channel):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
141 if not size:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
142 return b''
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
143 assert size > 0
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
144
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
145 # tell the client we need at most size bytes
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
146 self.out.write(struct.pack(b'>cI', channel, size))
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
147 self.out.flush()
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
148
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
149 length = self.in_.read(4)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
150 length = struct.unpack(b'>I', length)[0]
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
151 if not length:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
152 return b''
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
153 else:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
154 return self.in_.read(length)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
155
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
156 def readline(self, size=-1):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
157 if size < 0:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
158 size = self.maxchunksize
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
159 s = self._read(size, b'L')
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
160 buf = s
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
161 # keep asking for more until there's either no more or
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
162 # we got a full line
44373
98c14f0108b8 py3: fix EOL detection in commandserver.channeledinput
Yuya Nishihara <yuya@tcha.org>
parents: 43506
diff changeset
163 while s and not s.endswith(b'\n'):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
164 s = self._read(size, b'L')
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
165 buf += s
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
166
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
167 return buf
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
168 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
169 return self._read(size, b'L')
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
170
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
171 def __iter__(self):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
172 return self
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
173
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
174 def next(self):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
175 l = self.readline()
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
176 if not l:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
177 raise StopIteration
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
178 return l
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
179
40358
afbfcc4e3473 py3: alias next to __next__ in commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents: 40357
diff changeset
180 __next__ = next
afbfcc4e3473 py3: alias next to __next__ in commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents: 40357
diff changeset
181
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
182 def __getattr__(self, attr):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
183 if attr in ('isatty', 'fileno', 'tell', 'seek'):
18174
56ef99fbd6f2 commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents: 17425
diff changeset
184 raise AttributeError(attr)
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
185 return getattr(self.in_, attr)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
186
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
187
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
188 _messageencoders = {
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
189 b'cbor': lambda v: b''.join(cborutil.streamencode(v)),
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
190 }
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
191
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
192
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
193 def _selectmessageencoder(ui):
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
194 # experimental config: cmdserver.message-encodings
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
195 encnames = ui.configlist(b'cmdserver', b'message-encodings')
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
196 for n in encnames:
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
197 f = _messageencoders.get(n)
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
198 if f:
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
199 return n, f
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
200 raise error.Abort(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
201 b'no supported message encodings: %s' % b' '.join(encnames)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
202 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
203
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
204
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
205 class server(object):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
206 """
22990
a0e81aa94125 cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents: 22989
diff changeset
207 Listens for commands on fin, runs them and writes the output on a channel
a0e81aa94125 cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents: 22989
diff changeset
208 based stream to fout.
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
209 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
210
40875
e7110f44ee2d commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents: 40828
diff changeset
211 def __init__(self, ui, repo, fin, fout, prereposetups=None):
39818
24e493ec2229 py3: rename pycompat.getcwd() to encoding.getcwd() (API)
Matt Harbison <matt_harbison@yahoo.com>
parents: 38768
diff changeset
212 self.cwd = encoding.getcwd()
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
213
20650
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
214 if repo:
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
215 # the ui here is really the repo ui so take its baseui so we don't
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
216 # end up with its local configuration
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
217 self.ui = repo.baseui
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
218 self.repo = repo
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
219 self.repoui = repo.ui
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
220 else:
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
221 self.ui = ui
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
222 self.repo = self.repoui = None
40875
e7110f44ee2d commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents: 40828
diff changeset
223 self._prereposetups = prereposetups
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
224
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
225 self.cdebug = channeledoutput(fout, b'd')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
226 self.cerr = channeledoutput(fout, b'e')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
227 self.cout = channeledoutput(fout, b'o')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
228 self.cin = channeledinput(fin, fout, b'I')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
229 self.cresult = channeledoutput(fout, b'r')
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
230
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
231 if self.ui.config(b'cmdserver', b'log') == b'-':
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
232 # switch log stream of server's ui to the 'd' (debug) channel
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
233 # (don't touch repo.ui as its lifetime is longer than the server)
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
234 self.ui = self.ui.copy()
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
235 setuplogging(self.ui, repo=None, fp=self.cdebug)
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
236
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
237 # TODO: add this to help/config.txt when stabilized
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
238 # ``channel``
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
239 # Use separate channel for structured output. (Command-server only)
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
240 self.cmsg = None
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
241 if ui.config(b'ui', b'message-output') == b'channel':
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
242 encname, encfn = _selectmessageencoder(ui)
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
243 self.cmsg = channeledmessage(fout, b'm', encname, encfn)
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
244
22990
a0e81aa94125 cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents: 22989
diff changeset
245 self.client = fin
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
246
29512
538d0003c9e0 commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29511
diff changeset
247 def cleanup(self):
538d0003c9e0 commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29511
diff changeset
248 """release and restore resources taken during server session"""
538d0003c9e0 commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29511
diff changeset
249
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
250 def _read(self, size):
14706
5fd5dd9a610a cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents: 14647
diff changeset
251 if not size:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
252 return b''
14706
5fd5dd9a610a cmdserver: don't raise EOFError when trying to read 0 bytes from the client
Idan Kamara <idankk86@gmail.com>
parents: 14647
diff changeset
253
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
254 data = self.client.read(size)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
255
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
256 # is the other end closed?
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
257 if not data:
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 16683
diff changeset
258 raise EOFError
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
259
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
260 return data
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
261
28156
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
262 def _readstr(self):
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
263 """read a string from the channel
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
264
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
265 format:
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
266 data length (uint32), data
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
267 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
268 length = struct.unpack(b'>I', self._read(4))[0]
28156
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
269 if not length:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
270 return b''
28156
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
271 return self._read(length)
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
272
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
273 def _readlist(self):
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
274 """read a list of NULL separated strings from the channel"""
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
275 s = self._readstr()
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
276 if s:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
277 return s.split(b'\0')
28156
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
278 else:
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
279 return []
75f586a1bf55 commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents: 28027
diff changeset
280
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
281 def runcommand(self):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
282 """ reads a list of \0 terminated arguments, executes
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
283 and writes the return code to the result channel """
27352
9fd8f1552369 commandserver: cut import cycle by itself
Yuya Nishihara <yuya@tcha.org>
parents: 27351
diff changeset
284 from . import dispatch # avoid cycle
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
285
28157
e7c9b59dbbcf commandserver: use _readlist
Jun Wu <quark@fb.com>
parents: 28156
diff changeset
286 args = self._readlist()
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
287
14750
f5f97a0f983f cmdserver: copy repo.ui before running commands
Idan Kamara <idankk86@gmail.com>
parents: 14728
diff changeset
288 # copy the uis so changes (e.g. --config or --verbose) don't
f5f97a0f983f cmdserver: copy repo.ui before running commands
Idan Kamara <idankk86@gmail.com>
parents: 14728
diff changeset
289 # persist between requests
14751
712954a67be3 cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents: 14750
diff changeset
290 copiedui = self.ui.copy()
21195
9336bc7dca8e cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents: 20650
diff changeset
291 uis = [copiedui]
20650
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
292 if self.repo:
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
293 self.repo.baseui = copiedui
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
294 # clone ui without using ui.copy because this is protected
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
295 repoui = self.repoui.__class__(self.repoui)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
296 repoui.copy = copiedui.copy # redo copy protection
21195
9336bc7dca8e cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents: 20650
diff changeset
297 uis.append(repoui)
20650
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
298 self.repo.ui = self.repo.dirstate._ui = repoui
e811b93f2cb1 cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents: 20631
diff changeset
299 self.repo.invalidateall()
14751
712954a67be3 cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents: 14750
diff changeset
300
21195
9336bc7dca8e cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents: 20650
diff changeset
301 for ui in uis:
29366
d269e7db2f55 ui: provide official way to reset internal state per command
Yuya Nishihara <yuya@tcha.org>
parents: 28511
diff changeset
302 ui.resetstate()
27565
e7937438e3f7 commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents: 27415
diff changeset
303 # any kind of interaction must use server channels, but chg may
e7937438e3f7 commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents: 27415
diff changeset
304 # replace channels by fully functional tty files. so nontty is
e7937438e3f7 commandserver: do not set nontty flag if channel is replaced by a real file
Yuya Nishihara <yuya@tcha.org>
parents: 27415
diff changeset
305 # enforced only if cin is a channel.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
306 if not util.safehasattr(self.cin, b'fileno'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
307 ui.setconfig(b'ui', b'nontty', b'true', b'commandserver')
21195
9336bc7dca8e cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents: 20650
diff changeset
308
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
309 req = dispatch.request(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
310 args[:],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
311 copiedui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
312 self.repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
313 self.cin,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
314 self.cout,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
315 self.cerr,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
316 self.cmsg,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
317 prereposetups=self._prereposetups,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
318 )
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
319
35652
40da2d7b4871 commandserver: restore cwd in case of exception
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35461
diff changeset
320 try:
37995
6f9ac3cb0987 dispatch: unify handling of None returned by a command function
Yuya Nishihara <yuya@tcha.org>
parents: 37124
diff changeset
321 ret = dispatch.dispatch(req) & 255
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
322 self.cresult.write(struct.pack(b'>i', int(ret)))
35652
40da2d7b4871 commandserver: restore cwd in case of exception
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35461
diff changeset
323 finally:
40da2d7b4871 commandserver: restore cwd in case of exception
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35461
diff changeset
324 # restore old cwd
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
325 if b'--cwd' in args:
35652
40da2d7b4871 commandserver: restore cwd in case of exception
Gregory Szorc <gregory.szorc@gmail.com>
parents: 35461
diff changeset
326 os.chdir(self.cwd)
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
327
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
328 def getencoding(self):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
329 """ writes the current encoding to the result channel """
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
330 self.cresult.write(encoding.encoding)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
331
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
332 def serveone(self):
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
333 cmd = self.client.readline()[:-1]
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
334 if cmd:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
335 handler = self.capabilities.get(cmd)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
336 if handler:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
337 handler(self)
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
338 else:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
339 # clients are expected to check what commands are supported by
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
340 # looking at the servers capabilities
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
341 raise error.Abort(_(b'unknown command %s') % cmd)
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
342
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
343 return cmd != b''
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
344
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
345 capabilities = {b'runcommand': runcommand, b'getencoding': getencoding}
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
346
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
347 def serve(self):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
348 hellomsg = b'capabilities: ' + b' '.join(sorted(self.capabilities))
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
349 hellomsg += b'\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
350 hellomsg += b'encoding: ' + encoding.encoding
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
351 hellomsg += b'\n'
40589
054d0fcba2c4 commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents: 40588
diff changeset
352 if self.cmsg:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
353 hellomsg += b'message-encoding: %s\n' % self.cmsg.encoding
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
354 hellomsg += b'pid: %d' % procutil.getpid()
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
355 if util.safehasattr(os, b'getpgid'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
356 hellomsg += b'\n'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
357 hellomsg += b'pgid: %d' % os.getpgid(0)
14719
c19de7f32961 cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents: 14707
diff changeset
358
c19de7f32961 cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents: 14707
diff changeset
359 # write the hello msg in -one- chunk
c19de7f32961 cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents: 14707
diff changeset
360 self.cout.write(hellomsg)
14647
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
361
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
362 try:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
363 while self.serveone():
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
364 pass
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
365 except EOFError:
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
366 # we'll get here if the client disconnected while we were reading
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
367 # its request
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
368 return 1
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
369
2e9f379de0ac serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff changeset
370 return 0
22988
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
371
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
372
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
373 def setuplogging(ui, repo=None, fp=None):
40823
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
374 """Set up server logging facility
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
375
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
376 If cmdserver.log is '-', log messages will be sent to the given fp.
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
377 It should be the 'd' channel while a client is connected, and otherwise
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
378 is the stderr of the server process.
40823
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
379 """
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
380 # developer config: cmdserver.log
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
381 logpath = ui.config(b'cmdserver', b'log')
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
382 if not logpath:
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
383 return
40827
d23fd01cc115 commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents: 40826
diff changeset
384 # developer config: cmdserver.track-log
d23fd01cc115 commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents: 40826
diff changeset
385 tracked = set(ui.configlist(b'cmdserver', b'track-log'))
40823
368ecbf734af commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents: 40819
diff changeset
386
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
387 if logpath == b'-' and fp:
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
388 logger = loggingutil.fileobjectlogger(fp, tracked)
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
389 elif logpath == b'-':
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
390 logger = loggingutil.fileobjectlogger(ui.ferr, tracked)
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
391 else:
40826
1617aa916d88 commandserver: expand log path for convenience
Yuya Nishihara <yuya@tcha.org>
parents: 40825
diff changeset
392 logpath = os.path.abspath(util.expandpath(logpath))
40827
d23fd01cc115 commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents: 40826
diff changeset
393 # developer config: cmdserver.max-log-files
d23fd01cc115 commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents: 40826
diff changeset
394 maxfiles = ui.configint(b'cmdserver', b'max-log-files')
d23fd01cc115 commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents: 40826
diff changeset
395 # developer config: cmdserver.max-log-size
d23fd01cc115 commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents: 40826
diff changeset
396 maxsize = ui.configbytes(b'cmdserver', b'max-log-size')
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
397 vfs = vfsmod.vfs(os.path.dirname(logpath))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
398 logger = loggingutil.filelogger(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
399 vfs,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
400 os.path.basename(logpath),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
401 tracked,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
402 maxfiles=maxfiles,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
403 maxsize=maxsize,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
404 )
40824
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
405
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
406 targetuis = {ui}
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
407 if repo:
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
408 targetuis.add(repo.baseui)
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
409 targetuis.add(repo.ui)
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
410 for u in targetuis:
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
411 u.setlogger(b'cmdserver', logger)
82210d88d814 commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents: 40823
diff changeset
412
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
413
22988
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
414 class pipeservice(object):
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
415 def __init__(self, ui, repo, opts):
23323
bc374458688b cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents: 23322
diff changeset
416 self.ui = ui
bc374458688b cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents: 23322
diff changeset
417 self.repo = repo
22988
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
418
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
419 def init(self):
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
420 pass
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
421
32b77aba2772 cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents: 22563
diff changeset
422 def run(self):
23323
bc374458688b cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents: 23322
diff changeset
423 ui = self.ui
23324
69f86b937035 cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents: 23323
diff changeset
424 # redirect stdio to null device so that broken extensions or in-process
69f86b937035 cmdserver: protect pipe server streams against corruption caused by direct io
Yuya Nishihara <yuya@tcha.org>
parents: 23323
diff changeset
425 # hooks will never cause corruption of channel protocol.
41284
b0e3f2d7c143 ui: move protectedstdio() context manager from procutil
Yuya Nishihara <yuya@tcha.org>
parents: 40999
diff changeset
426 with ui.protectedfinout() as (fin, fout):
40588
9683dfb6f13a commandserver: fix reference before assignment error in pipeservice cleanup
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
427 sv = server(ui, self.repo, fin, fout)
37124
6715e8035b4f procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents: 37123
diff changeset
428 try:
6715e8035b4f procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents: 37123
diff changeset
429 return sv.serve()
6715e8035b4f procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents: 37123
diff changeset
430 finally:
6715e8035b4f procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents: 37123
diff changeset
431 sv.cleanup()
22989
dc8803ce3dfe cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents: 22988
diff changeset
432
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
433
29586
42cdba9cfee4 commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents: 29585
diff changeset
434 def _initworkerprocess():
29609
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
435 # use a different process group from the master process, in order to:
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
436 # 1. make the current process group no longer "orphaned" (because the
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
437 # parent of this process is in a different process group while
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
438 # remains in a same session)
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
439 # according to POSIX 2.2.2.52, orphaned process group will ignore
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
440 # terminal-generated stop signals like SIGTSTP (Ctrl+Z), which will
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
441 # cause trouble for things like ncurses.
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
442 # 2. the client can use kill(-pgid, sig) to simulate terminal-generated
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
443 # SIGINT (Ctrl+C) and process-exit-generated SIGHUP. our child
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
444 # processes like ssh will be killed properly, without affecting
591c3badff2e commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents: 29588
diff changeset
445 # unrelated processes.
29585
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
446 os.setpgid(0, 0)
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
447 # change random state otherwise forked request handlers would have a
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
448 # same state inherited from parent.
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
449 random.seed()
29542
6011ad3b0a42 commandserver: manually create file objects from socket
Yuya Nishihara <yuya@tcha.org>
parents: 29532
diff changeset
450
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
451
40875
e7110f44ee2d commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents: 40828
diff changeset
452 def _serverequest(ui, repo, conn, createcmdserver, prereposetups):
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
453 fin = conn.makefile('rb')
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
454 fout = conn.makefile('wb')
29585
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
455 sv = None
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
456 try:
40875
e7110f44ee2d commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents: 40828
diff changeset
457 sv = createcmdserver(repo, conn, fin, fout, prereposetups)
22994
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
458 try:
29585
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
459 sv.serve()
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
460 # handle exceptions that may be raised by command server. most of
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
461 # known exceptions are caught by dispatch.
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
462 except error.Abort as inst:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
463 ui.error(_(b'abort: %s\n') % inst)
29585
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
464 except IOError as inst:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
465 if inst.errno != errno.EPIPE:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
466 raise
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
467 except KeyboardInterrupt:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
468 pass
29513
e5b4d79a9140 commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents: 29512
diff changeset
469 finally:
29585
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
470 sv.cleanup()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
471 except: # re-raises
29585
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
472 # also write traceback to error channel. otherwise client cannot
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
473 # see it because it is written to server's stderr by default.
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
474 if sv:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
475 cerr = sv.cerr
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
476 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
477 cerr = channeledoutput(fout, b'e')
40361
b7de186efd82 py3: don't use traceback.print_exc() in commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents: 40359
diff changeset
478 cerr.write(encoding.strtolocal(traceback.format_exc()))
29585
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
479 raise
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
480 finally:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
481 fin.close()
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
482 try:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
483 fout.close() # implicit flush() may cause another EPIPE
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
484 except IOError as inst:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
485 if inst.errno != errno.EPIPE:
6ed452d0f1f1 commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents: 29580
diff changeset
486 raise
22994
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
487
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
488
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
489 class unixservicehandler(object):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
490 """Set of pluggable operations for unix-mode services
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
491
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
492 Almost all methods except for createcmdserver() are called in the main
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
493 process. You can't pass mutable resource back from createcmdserver().
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
494 """
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
495
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
496 pollinterval = None
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
497
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
498 def __init__(self, ui):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
499 self.ui = ui
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
500
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
501 def bindsocket(self, sock, address):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
502 util.bindunixsocket(sock, address)
32236
c8b9943c07eb commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents: 30924
diff changeset
503 sock.listen(socket.SOMAXCONN)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
504 self.ui.status(_(b'listening at %s\n') % address)
32237
1ada3d18e7fb commandserver: move printbanner logic to bindsocket
Jun Wu <quark@fb.com>
parents: 32236
diff changeset
505 self.ui.flush() # avoid buffering of status message
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
506
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
507 def unlinksocket(self, address):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
508 os.unlink(address)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
509
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
510 def shouldexit(self):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
511 """True if server should shut down; checked per pollinterval"""
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
512 return False
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
513
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
514 def newconnection(self):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
515 """Called when main process notices new connection"""
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
516
40875
e7110f44ee2d commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents: 40828
diff changeset
517 def createcmdserver(self, repo, conn, fin, fout, prereposetups):
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
518 """Create new command server instance; called in the process that
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
519 serves for the current connection"""
40875
e7110f44ee2d commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents: 40828
diff changeset
520 return server(self.ui, repo, fin, fout, prereposetups)
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
521
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
522
29548
9da1adc18639 commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents: 29544
diff changeset
523 class unixforkingservice(object):
22994
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
524 """
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
525 Listens on unix domain socket and forks server per connection
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
526 """
29548
9da1adc18639 commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents: 29544
diff changeset
527
9da1adc18639 commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents: 29544
diff changeset
528 def __init__(self, ui, repo, opts, handler=None):
22994
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
529 self.ui = ui
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
530 self.repo = repo
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
531 self.address = opts[b'address']
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
532 if not util.safehasattr(socket, b'AF_UNIX'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
533 raise error.Abort(_(b'unsupported platform'))
22994
840be5ca03e1 cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents: 22990
diff changeset
534 if not self.address:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
535 raise error.Abort(_(b'no socket path specified with --address'))
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
536 self._servicehandler = handler or unixservicehandler(ui)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
537 self._sock = None
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
538 self._mainipc = None
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
539 self._workeripc = None
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
540 self._oldsigchldhandler = None
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
541 self._workerpids = set() # updated by signal handler; do not iterate
30887
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
542 self._socketunlinked = None
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
543 # experimental config: cmdserver.max-repo-cache
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
544 maxlen = ui.configint(b'cmdserver', b'max-repo-cache')
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
545 if maxlen < 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
546 raise error.Abort(_(b'negative max-repo-cache size not allowed'))
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
547 self._repoloader = repocache.repoloader(ui, maxlen)
44368
6392bd7c26a8 darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents: 43506
diff changeset
548 # attempt to avoid crash in CoreFoundation when using chg after fix in
6392bd7c26a8 darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents: 43506
diff changeset
549 # a89381e04c58
6392bd7c26a8 darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents: 43506
diff changeset
550 if pycompat.isdarwin:
6392bd7c26a8 darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents: 43506
diff changeset
551 procutil.gui()
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
552
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
553 def init(self):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
554 self._sock = socket.socket(socket.AF_UNIX)
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
555 # IPC channel from many workers to one main process; this is actually
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
556 # a uni-directional pipe, but is backed by a DGRAM socket so each
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
557 # message can be easily separated.
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
558 o = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
559 self._mainipc, self._workeripc = o
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
560 self._servicehandler.bindsocket(self._sock, self.address)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
561 if util.safehasattr(procutil, b'unblocksignal'):
37120
a8a902d7176e procutil: bulk-replace function calls to point to new module
Yuya Nishihara <yuya@tcha.org>
parents: 37119
diff changeset
562 procutil.unblocksignal(signal.SIGCHLD)
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
563 o = signal.signal(signal.SIGCHLD, self._sigchldhandler)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
564 self._oldsigchldhandler = o
30887
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
565 self._socketunlinked = False
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
566 self._repoloader.start()
30887
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
567
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
568 def _unlinksocket(self):
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
569 if not self._socketunlinked:
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
570 self._servicehandler.unlinksocket(self.address)
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
571 self._socketunlinked = True
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
572
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
573 def _cleanup(self):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
574 signal.signal(signal.SIGCHLD, self._oldsigchldhandler)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
575 self._sock.close()
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
576 self._mainipc.close()
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
577 self._workeripc.close()
30887
a95fc01aaffe commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents: 30519
diff changeset
578 self._unlinksocket()
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
579 self._repoloader.stop()
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
580 # don't kill child processes as they have active clients, just wait
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
581 self._reapworkers(0)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
582
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
583 def run(self):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
584 try:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
585 self._mainloop()
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
586 finally:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
587 self._cleanup()
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
588
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
589 def _mainloop(self):
30891
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
590 exiting = False
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
591 h = self._servicehandler
36940
b0ffcb540357 commandserver: prefer first-party selectors module from Python 3 to backport
Augie Fackler <augie@google.com>
parents: 36835
diff changeset
592 selector = selectors.DefaultSelector()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
593 selector.register(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
594 self._sock, selectors.EVENT_READ, self._acceptnewconnection
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
595 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
596 selector.register(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
597 self._mainipc, selectors.EVENT_READ, self._handlemainipc
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
598 )
30891
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
599 while True:
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
600 if not exiting and h.shouldexit():
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
601 # clients can no longer connect() to the domain socket, so
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
602 # we stop queuing new requests.
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
603 # for requests that are queued (connect()-ed, but haven't been
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
604 # accept()-ed), handle them before exit. otherwise, clients
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
605 # waiting for recv() will receive ECONNRESET.
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
606 self._unlinksocket()
b1b36c6499c2 commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents: 30887
diff changeset
607 exiting = True
40788
41f0529b5112 commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
608 try:
40878
2525faf4ecdb commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents: 40877
diff changeset
609 events = selector.select(timeout=h.pollinterval)
40788
41f0529b5112 commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
610 except OSError as inst:
41f0529b5112 commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
611 # selectors2 raises ETIMEDOUT if timeout exceeded while
41f0529b5112 commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
612 # handling signal interrupt. That's probably wrong, but
41f0529b5112 commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
613 # we can easily get around it.
41f0529b5112 commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
614 if inst.errno != errno.ETIMEDOUT:
41f0529b5112 commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents: 40361
diff changeset
615 raise
40878
2525faf4ecdb commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents: 40877
diff changeset
616 events = []
2525faf4ecdb commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents: 40877
diff changeset
617 if not events:
33543
3ef3bf704e47 commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents: 33506
diff changeset
618 # only exit if we completed all queued requests
3ef3bf704e47 commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents: 33506
diff changeset
619 if exiting:
3ef3bf704e47 commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents: 33506
diff changeset
620 break
3ef3bf704e47 commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents: 33506
diff changeset
621 continue
40878
2525faf4ecdb commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents: 40877
diff changeset
622 for key, _mask in events:
2525faf4ecdb commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents: 40877
diff changeset
623 key.data(key.fileobj, selector)
40876
dc9901558e3c commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents: 40875
diff changeset
624 selector.close()
dc9901558e3c commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents: 40875
diff changeset
625
dc9901558e3c commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents: 40875
diff changeset
626 def _acceptnewconnection(self, sock, selector):
dc9901558e3c commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents: 40875
diff changeset
627 h = self._servicehandler
40877
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
628 try:
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
629 conn, _addr = sock.accept()
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
630 except socket.error as inst:
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
631 if inst.args[0] == errno.EINTR:
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
632 return
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
633 raise
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
634
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
635 # Future improvement: On Python 3.7, maybe gc.freeze() can be used
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
636 # to prevent COW memory from being touched by GC.
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
637 # https://instagram-engineering.com/
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
638 # copy-on-write-friendly-python-garbage-collection-ad6ed5233ddf
40877
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
639 pid = os.fork()
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
640 if pid:
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
641 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
642 self.ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
643 b'cmdserver', b'forked worker process (pid=%d)\n', pid
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
644 )
40877
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
645 self._workerpids.add(pid)
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
646 h.newconnection()
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
647 finally:
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
648 conn.close() # release handle in parent process
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
649 else:
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
650 try:
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
651 selector.close()
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
652 sock.close()
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
653 self._mainipc.close()
40877
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
654 self._runworker(conn)
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
655 conn.close()
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
656 self._workeripc.close()
40877
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
657 os._exit(0)
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
658 except: # never return, hence no re-raises
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
659 try:
40877
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
660 self.ui.traceback(force=True)
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
661 finally:
40877
9f00de4dc7cb commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents: 40876
diff changeset
662 os._exit(255)
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
663
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
664 def _handlemainipc(self, sock, selector):
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
665 """Process messages sent from a worker"""
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
666 try:
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
667 path = sock.recv(32768) # large enough to receive path
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
668 except socket.error as inst:
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
669 if inst.args[0] == errno.EINTR:
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
670 return
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
671 raise
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
672 self._repoloader.load(path)
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
673
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
674 def _sigchldhandler(self, signal, frame):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
675 self._reapworkers(os.WNOHANG)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
676
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
677 def _reapworkers(self, options):
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
678 while self._workerpids:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
679 try:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
680 pid, _status = os.waitpid(-1, options)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
681 except OSError as inst:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
682 if inst.errno == errno.EINTR:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
683 continue
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
684 if inst.errno != errno.ECHILD:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
685 raise
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
686 # no child processes at all (reaped by other waitpid()?)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
687 self._workerpids.clear()
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
688 return
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
689 if pid == 0:
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
690 # no waitable child processes
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
691 return
40828
25e9089c7686 commandserver: turn server debug messages into logs
Yuya Nishihara <yuya@tcha.org>
parents: 40827
diff changeset
692 self.ui.log(b'cmdserver', b'worker process exited (pid=%d)\n', pid)
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
693 self._workerpids.discard(pid)
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
694
29587
536eec443b4a commandserver: rename _serveworker() to _runworker()
Yuya Nishihara <yuya@tcha.org>
parents: 29586
diff changeset
695 def _runworker(self, conn):
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
696 signal.signal(signal.SIGCHLD, self._oldsigchldhandler)
29586
42cdba9cfee4 commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents: 29585
diff changeset
697 _initworkerprocess()
29544
024e8f82f3de commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents: 29543
diff changeset
698 h = self._servicehandler
29586
42cdba9cfee4 commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents: 29585
diff changeset
699 try:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
700 _serverequest(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
701 self.ui,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
702 self.repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
703 conn,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
704 h.createcmdserver,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
705 prereposetups=[self._reposetup],
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
706 )
29586
42cdba9cfee4 commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents: 29585
diff changeset
707 finally:
42cdba9cfee4 commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents: 29585
diff changeset
708 gc.collect() # trigger __del__ since worker process uses os._exit
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
709
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
710 def _reposetup(self, ui, repo):
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
711 if not repo.local():
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
712 return
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
713
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
714 class unixcmdserverrepo(repo.__class__):
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
715 def close(self):
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
716 super(unixcmdserverrepo, self).close()
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
717 try:
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
718 self._cmdserveripc.send(self.root)
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
719 except socket.error:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
720 self.ui.log(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
721 b'cmdserver', b'failed to send repo root to master\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 41284
diff changeset
722 )
40998
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
723
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
724 repo.__class__ = unixcmdserverrepo
042ed354b9eb commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents: 40878
diff changeset
725 repo._cmdserveripc = self._workeripc
40999
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
726
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
727 cachedrepo = self._repoloader.get(repo.root)
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
728 if cachedrepo is None:
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
729 return
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
730 repo.ui.log(b'repocache', b'repo from cache: %s\n', repo.root)
dcac24ec935b commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents: 40998
diff changeset
731 repocache.copycache(cachedrepo, repo)