Mercurial > hg
annotate mercurial/commandserver.py @ 43095:fb41ea2ea076
formatting: introduce a `test-check-format-black.t` that enforce formatting
This should prevent use to drift away from the expect format.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 07 Oct 2019 11:52:58 -0400 |
parents | c59eb1560c44 |
children | 9f70512ae2cf |
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): |
40357
efbf7de09d2a
py3: system-stringify list of attributes to be forwarded from commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents:
39818
diff
changeset
|
67 if attr in (r'isatty', r'fileno', r'tell', r'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 |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
163 while s and s[-1] != b'\n': |
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): |
40357
efbf7de09d2a
py3: system-stringify list of attributes to be forwarded from commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents:
39818
diff
changeset
|
183 if attr in (r'isatty', r'fileno', r'tell', r'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 | 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): |
40359
558114fa7bc1
py3: system-stringify file mode in commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents:
40358
diff
changeset
|
453 fin = conn.makefile(r'rb') |
558114fa7bc1
py3: system-stringify file mode in commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents:
40358
diff
changeset
|
454 fout = conn.makefile(r'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) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
548 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
549 def init(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
550 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
|
551 # 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
|
552 # 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
|
553 # 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
|
554 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
|
555 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
|
556 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
|
557 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
|
558 procutil.unblocksignal(signal.SIGCHLD) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
559 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
|
560 self._oldsigchldhandler = o |
30887
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
561 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
|
562 self._repoloader.start() |
30887
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
563 |
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
564 def _unlinksocket(self): |
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
565 if not self._socketunlinked: |
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
566 self._servicehandler.unlinksocket(self.address) |
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
567 self._socketunlinked = True |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
568 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
569 def _cleanup(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
570 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
|
571 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
|
572 self._mainipc.close() |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
573 self._workeripc.close() |
30887
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
574 self._unlinksocket() |
40999
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
575 self._repoloader.stop() |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
576 # 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
|
577 self._reapworkers(0) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
578 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
579 def run(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
580 try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
581 self._mainloop() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
582 finally: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
583 self._cleanup() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
584 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
585 def _mainloop(self): |
30891
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
586 exiting = False |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
587 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
|
588 selector = selectors.DefaultSelector() |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
589 selector.register( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
590 self._sock, selectors.EVENT_READ, self._acceptnewconnection |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
591 ) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
592 selector.register( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
593 self._mainipc, selectors.EVENT_READ, self._handlemainipc |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
594 ) |
30891
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
595 while True: |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
596 if not exiting and h.shouldexit(): |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
597 # 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
|
598 # we stop queuing new requests. |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
599 # 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
|
600 # accept()-ed), handle them before exit. otherwise, clients |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
601 # waiting for recv() will receive ECONNRESET. |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
602 self._unlinksocket() |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
603 exiting = True |
40788
41f0529b5112
commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents:
40361
diff
changeset
|
604 try: |
40878
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
605 events = selector.select(timeout=h.pollinterval) |
40788
41f0529b5112
commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents:
40361
diff
changeset
|
606 except OSError as inst: |
41f0529b5112
commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents:
40361
diff
changeset
|
607 # selectors2 raises ETIMEDOUT if timeout exceeded while |
41f0529b5112
commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents:
40361
diff
changeset
|
608 # 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
|
609 # we can easily get around it. |
41f0529b5112
commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents:
40361
diff
changeset
|
610 if inst.errno != errno.ETIMEDOUT: |
41f0529b5112
commandserver: get around ETIMEDOUT raised by selectors2
Yuya Nishihara <yuya@tcha.org>
parents:
40361
diff
changeset
|
611 raise |
40878
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
612 events = [] |
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
613 if not events: |
33543
3ef3bf704e47
commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents:
33506
diff
changeset
|
614 # 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
|
615 if exiting: |
3ef3bf704e47
commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents:
33506
diff
changeset
|
616 break |
3ef3bf704e47
commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents:
33506
diff
changeset
|
617 continue |
40878
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
618 for key, _mask in events: |
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
619 key.data(key.fileobj, selector) |
40876
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
620 selector.close() |
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
621 |
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
622 def _acceptnewconnection(self, sock, selector): |
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
623 h = self._servicehandler |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
624 try: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
625 conn, _addr = sock.accept() |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
626 except socket.error as inst: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
627 if inst.args[0] == errno.EINTR: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
628 return |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
629 raise |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
630 |
40999
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
631 # 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
|
632 # 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
|
633 # 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
|
634 # 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
|
635 pid = os.fork() |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
636 if pid: |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
637 try: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
638 self.ui.log( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
639 b'cmdserver', b'forked worker process (pid=%d)\n', pid |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
640 ) |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
641 self._workerpids.add(pid) |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
642 h.newconnection() |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
643 finally: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
644 conn.close() # release handle in parent process |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
645 else: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
646 try: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
647 selector.close() |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
648 sock.close() |
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
649 self._mainipc.close() |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
650 self._runworker(conn) |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
651 conn.close() |
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
652 self._workeripc.close() |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
653 os._exit(0) |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
654 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
|
655 try: |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
656 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
|
657 finally: |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
658 os._exit(255) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
659 |
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
660 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
|
661 """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
|
662 try: |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
663 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
|
664 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
|
665 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
|
666 return |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
667 raise |
40999
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
668 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
|
669 |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
670 def _sigchldhandler(self, signal, frame): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
671 self._reapworkers(os.WNOHANG) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
672 |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
673 def _reapworkers(self, options): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
674 while self._workerpids: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
675 try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
676 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
|
677 except OSError as inst: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
678 if inst.errno == errno.EINTR: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
679 continue |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
680 if inst.errno != errno.ECHILD: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
681 raise |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
682 # 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
|
683 self._workerpids.clear() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
684 return |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
685 if pid == 0: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
686 # no waitable child processes |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
687 return |
40828
25e9089c7686
commandserver: turn server debug messages into logs
Yuya Nishihara <yuya@tcha.org>
parents:
40827
diff
changeset
|
688 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
|
689 self._workerpids.discard(pid) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
690 |
29587
536eec443b4a
commandserver: rename _serveworker() to _runworker()
Yuya Nishihara <yuya@tcha.org>
parents:
29586
diff
changeset
|
691 def _runworker(self, conn): |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
692 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
|
693 _initworkerprocess() |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
694 h = self._servicehandler |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
695 try: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
696 _serverequest( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
697 self.ui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
698 self.repo, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
699 conn, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
700 h.createcmdserver, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
701 prereposetups=[self._reposetup], |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
702 ) |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
703 finally: |
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
704 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
|
705 |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
706 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
|
707 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
|
708 return |
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 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
|
711 def close(self): |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
712 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
|
713 try: |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
714 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
|
715 except socket.error: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
716 self.ui.log( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
717 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
|
718 ) |
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
719 |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
720 repo.__class__ = unixcmdserverrepo |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
721 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
|
722 |
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
723 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
|
724 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
|
725 return |
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
726 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
|
727 repocache.copycache(cachedrepo, repo) |