author | C. Masloch <pushbx@ulukai.org> |
Wed, 20 Apr 2022 19:24:39 +0200 | |
changeset 49449 | cfff73cab721 |
parent 49304 | 48f1b314056b |
child 50557 | 6e749d4abf05 |
permissions | -rw-r--r-- |
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 |
# |
46819
d4ba4d51f85f
contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents:
46101
diff
changeset
|
3 |
# Copyright Olivia Mackall <olivia@selenic.com> |
14647
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 |
|
29513
e5b4d79a9140
commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29512
diff
changeset
|
9 |
import gc |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
10 |
import os |
29513
e5b4d79a9140
commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29512
diff
changeset
|
11 |
import random |
49280
311fcc5a65f6
thirdparty: remove Python 2-specific selectors2 copy
Manuel Jacob <me@manueljacob.de>
parents:
48946
diff
changeset
|
12 |
import selectors |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
13 |
import signal |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
14 |
import socket |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
15 |
import struct |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
16 |
import traceback |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
17 |
|
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
18 |
from .i18n import _ |
43089
c59eb1560c44
py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents:
43077
diff
changeset
|
19 |
from .pycompat import getattr |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
20 |
from . import ( |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
21 |
encoding, |
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
22 |
error, |
40824
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
23 |
loggingutil, |
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
24 |
pycompat, |
40999
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
25 |
repocache, |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
26 |
util, |
40824
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
27 |
vfs as vfsmod, |
27351
28e50c4b15ed
commandserver: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents:
26587
diff
changeset
|
28 |
) |
37119
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36940
diff
changeset
|
29 |
from .utils import ( |
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
30 |
cborutil, |
37119
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36940
diff
changeset
|
31 |
procutil, |
d4a2e0d5d042
procutil: bulk-replace util.std* to point to new module
Yuya Nishihara <yuya@tcha.org>
parents:
36940
diff
changeset
|
32 |
) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
33 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
34 |
|
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
35 |
class channeledoutput: |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
36 |
""" |
22561
1120b1e2f975
cmdserver: correct doc of channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
21195
diff
changeset
|
37 |
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
|
38 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
39 |
data length (unsigned int), |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
40 |
data |
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 |
|
22563
8cc5e673cac0
cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
22562
diff
changeset
|
43 |
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
|
44 |
self.out = out |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
45 |
self.channel = channel |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
46 |
|
27415
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
47 |
@property |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
48 |
def name(self): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
49 |
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
|
50 |
|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
51 |
def write(self, data): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
52 |
if not data: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
53 |
return |
30263
7f2313450e86
cmdserver: write channel header and payload by a single write() call
Yuya Nishihara <yuya@tcha.org>
parents:
29609
diff
changeset
|
54 |
# 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
|
55 |
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
|
56 |
self.out.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
57 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
58 |
def __getattr__(self, attr): |
43506
9f70512ae2cf
cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents:
43089
diff
changeset
|
59 |
if attr in ('isatty', 'fileno', 'tell', 'seek'): |
18174
56ef99fbd6f2
commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents:
17425
diff
changeset
|
60 |
raise AttributeError(attr) |
22563
8cc5e673cac0
cmdserver: drop useless in_ attribute from channeledoutput
Yuya Nishihara <yuya@tcha.org>
parents:
22562
diff
changeset
|
61 |
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
|
62 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
63 |
|
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
64 |
class channeledmessage: |
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
65 |
""" |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
66 |
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
|
67 |
|
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
68 |
data length (unsigned int), |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
69 |
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
|
70 |
|
83dd8c63a0c6
ui: extract helpers to write message with type or label
Yuya Nishihara <yuya@tcha.org>
parents:
40589
diff
changeset
|
71 |
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
|
72 |
should be ignored. |
40589
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 |
|
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
75 |
# 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
|
76 |
structured = True |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
77 |
|
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
78 |
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
|
79 |
self._cout = channeledoutput(out, channel) |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
80 |
self.encoding = encodename |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
81 |
self._encodefn = encodefn |
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 |
def write(self, data, **opts): |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
84 |
opts = pycompat.byteskwargs(opts) |
40594
234c2d8c9e48
commandserver: send raw progress information to message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40590
diff
changeset
|
85 |
if data is not None: |
234c2d8c9e48
commandserver: send raw progress information to message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40590
diff
changeset
|
86 |
opts[b'data'] = data |
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
87 |
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
|
88 |
|
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
89 |
def __getattr__(self, attr): |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
90 |
return getattr(self._cout, attr) |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
91 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
92 |
|
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
93 |
class channeledinput: |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
94 |
""" |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
95 |
Read data from in_. |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
96 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
97 |
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
|
98 |
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
|
99 |
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
|
100 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
101 |
The client replies with: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
102 |
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
|
103 |
data |
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 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
106 |
maxchunksize = 4 * 1024 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
107 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
108 |
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
|
109 |
self.in_ = in_ |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
110 |
self.out = out |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
111 |
self.channel = channel |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
112 |
|
27415
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
113 |
@property |
f4ca33e33781
commandserver: implement name() to clarify channel is not a plain file
Yuya Nishihara <yuya@tcha.org>
parents:
27352
diff
changeset
|
114 |
def name(self): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
115 |
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
|
116 |
|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
117 |
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
|
118 |
if size < 0: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
119 |
# 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
|
120 |
# 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
|
121 |
size = self.maxchunksize |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
122 |
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
|
123 |
buf = s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
124 |
while s: |
14728
350dcd481410
cmdserver: fix read-loop string concatenation
Idan Kamara <idankk86@gmail.com>
parents:
14719
diff
changeset
|
125 |
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
|
126 |
buf += s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
127 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
128 |
return buf |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
129 |
else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
130 |
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
|
131 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
132 |
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
|
133 |
if not size: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
134 |
return b'' |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
135 |
assert size > 0 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
136 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
137 |
# 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
|
138 |
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
|
139 |
self.out.flush() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
140 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
141 |
length = self.in_.read(4) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
142 |
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
|
143 |
if not length: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
144 |
return b'' |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
145 |
else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
146 |
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
|
147 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
148 |
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
|
149 |
if size < 0: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
150 |
size = self.maxchunksize |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
151 |
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
|
152 |
buf = s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
153 |
# 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
|
154 |
# we got a full line |
44373
98c14f0108b8
py3: fix EOL detection in commandserver.channeledinput
Yuya Nishihara <yuya@tcha.org>
parents:
43506
diff
changeset
|
155 |
while s and not s.endswith(b'\n'): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
156 |
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
|
157 |
buf += s |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
158 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
159 |
return buf |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
160 |
else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
161 |
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
|
162 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
163 |
def __iter__(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
164 |
return self |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
165 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
166 |
def next(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
167 |
l = self.readline() |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
168 |
if not l: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
169 |
raise StopIteration |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
170 |
return l |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
171 |
|
40358
afbfcc4e3473
py3: alias next to __next__ in commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents:
40357
diff
changeset
|
172 |
__next__ = next |
afbfcc4e3473
py3: alias next to __next__ in commandserver.py
Yuya Nishihara <yuya@tcha.org>
parents:
40357
diff
changeset
|
173 |
|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
174 |
def __getattr__(self, attr): |
43506
9f70512ae2cf
cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents:
43089
diff
changeset
|
175 |
if attr in ('isatty', 'fileno', 'tell', 'seek'): |
18174
56ef99fbd6f2
commandserver: clean up use of two-argument raise
Augie Fackler <raf@durin42.com>
parents:
17425
diff
changeset
|
176 |
raise AttributeError(attr) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
177 |
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
|
178 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
179 |
|
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
180 |
_messageencoders = { |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
181 |
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
|
182 |
} |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
183 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
184 |
|
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
185 |
def _selectmessageencoder(ui): |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
186 |
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
|
187 |
for n in encnames: |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
188 |
f = _messageencoders.get(n) |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
189 |
if f: |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
190 |
return n, f |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
191 |
raise error.Abort( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
192 |
b'no supported message encodings: %s' % b' '.join(encnames) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
193 |
) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
194 |
|
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
195 |
|
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
196 |
class server: |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
197 |
""" |
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
198 |
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
|
199 |
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
|
200 |
""" |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
201 |
|
40875
e7110f44ee2d
commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents:
40828
diff
changeset
|
202 |
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
|
203 |
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
|
204 |
|
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
205 |
if repo: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
206 |
# 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
|
207 |
# end up with its local configuration |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
208 |
self.ui = repo.baseui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
209 |
self.repo = repo |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
210 |
self.repoui = repo.ui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
211 |
else: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
212 |
self.ui = ui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
213 |
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
|
214 |
self._prereposetups = prereposetups |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
215 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
216 |
self.cdebug = channeledoutput(fout, b'd') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
217 |
self.cerr = channeledoutput(fout, b'e') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
218 |
self.cout = channeledoutput(fout, b'o') |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
219 |
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
|
220 |
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
|
221 |
|
40824
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
222 |
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
|
223 |
# 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
|
224 |
# (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
|
225 |
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
|
226 |
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
|
227 |
|
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
228 |
self.cmsg = None |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
229 |
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
|
230 |
encname, encfn = _selectmessageencoder(ui) |
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
231 |
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
|
232 |
|
22990
a0e81aa94125
cmdserver: make server streams switchable
Yuya Nishihara <yuya@tcha.org>
parents:
22989
diff
changeset
|
233 |
self.client = fin |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
234 |
|
45057
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
235 |
# If shutdown-on-interrupt is off, the default SIGINT handler is |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
236 |
# removed so that client-server communication wouldn't be interrupted. |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
237 |
# For example, 'runcommand' handler will issue three short read()s. |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
238 |
# If one of the first two read()s were interrupted, the communication |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
239 |
# channel would be left at dirty state and the subsequent request |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
240 |
# wouldn't be parsed. So catching KeyboardInterrupt isn't enough. |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
241 |
self._shutdown_on_interrupt = ui.configbool( |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
242 |
b'cmdserver', b'shutdown-on-interrupt' |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
243 |
) |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
244 |
self._old_inthandler = None |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
245 |
if not self._shutdown_on_interrupt: |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
246 |
self._old_inthandler = signal.signal(signal.SIGINT, signal.SIG_IGN) |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
247 |
|
29512
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
248 |
def cleanup(self): |
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
249 |
"""release and restore resources taken during server session""" |
45057
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
250 |
if not self._shutdown_on_interrupt: |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
251 |
signal.signal(signal.SIGINT, self._old_inthandler) |
29512
538d0003c9e0
commandserver: promote .cleanup() hook from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29511
diff
changeset
|
252 |
|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
253 |
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
|
254 |
if not size: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
255 |
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
|
256 |
|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
257 |
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
|
258 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
259 |
# 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
|
260 |
if not data: |
16687
e34106fa0dc3
cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents:
16683
diff
changeset
|
261 |
raise EOFError |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
262 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
263 |
return data |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
264 |
|
28156
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
265 |
def _readstr(self): |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
266 |
"""read a string from the channel |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
267 |
|
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
268 |
format: |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
269 |
data length (uint32), data |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
270 |
""" |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
271 |
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
|
272 |
if not length: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
273 |
return b'' |
28156
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
274 |
return self._read(length) |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
275 |
|
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
276 |
def _readlist(self): |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
277 |
"""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
|
278 |
s = self._readstr() |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
279 |
if s: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
280 |
return s.split(b'\0') |
28156
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
281 |
else: |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
282 |
return [] |
75f586a1bf55
commandserver: add _readstr and _readlist
Jun Wu <quark@fb.com>
parents:
28027
diff
changeset
|
283 |
|
45057
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
284 |
def _dispatchcommand(self, req): |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
285 |
from . import dispatch # avoid cycle |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
286 |
|
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
287 |
if self._shutdown_on_interrupt: |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
288 |
# no need to restore SIGINT handler as it is unmodified. |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
289 |
return dispatch.dispatch(req) |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
290 |
|
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
291 |
try: |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
292 |
signal.signal(signal.SIGINT, self._old_inthandler) |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
293 |
return dispatch.dispatch(req) |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
294 |
except error.SignalInterrupt: |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
295 |
# propagate SIGBREAK, SIGHUP, or SIGTERM. |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
296 |
raise |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
297 |
except KeyboardInterrupt: |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
298 |
# SIGINT may be received out of the try-except block of dispatch(), |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
299 |
# so catch it as last ditch. Another KeyboardInterrupt may be |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
300 |
# raised while handling exceptions here, but there's no way to |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
301 |
# avoid that except for doing everything in C. |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
302 |
pass |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
303 |
finally: |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
304 |
signal.signal(signal.SIGINT, signal.SIG_IGN) |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
305 |
# On KeyboardInterrupt, print error message and exit *after* SIGINT |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
306 |
# handler removed. |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
307 |
req.ui.error(_(b'interrupted!\n')) |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
308 |
return -1 |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
309 |
|
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
310 |
def runcommand(self): |
45942
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45682
diff
changeset
|
311 |
"""reads a list of \0 terminated arguments, executes |
89a2afe31e82
formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents:
45682
diff
changeset
|
312 |
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
|
313 |
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
|
314 |
|
28157 | 315 |
args = self._readlist() |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
316 |
|
14750
f5f97a0f983f
cmdserver: copy repo.ui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14728
diff
changeset
|
317 |
# 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
|
318 |
# persist between requests |
14751
712954a67be3
cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14750
diff
changeset
|
319 |
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
|
320 |
uis = [copiedui] |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
321 |
if self.repo: |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
322 |
self.repo.baseui = copiedui |
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
323 |
# 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
|
324 |
repoui = self.repoui.__class__(self.repoui) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
325 |
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
|
326 |
uis.append(repoui) |
20650
e811b93f2cb1
cmdserver: allow to start server without repository
Yuya Nishihara <yuya@tcha.org>
parents:
20631
diff
changeset
|
327 |
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
|
328 |
self.repo.invalidateall() |
14751
712954a67be3
cmdserver: assign repo.baseui before running commands
Idan Kamara <idankk86@gmail.com>
parents:
14750
diff
changeset
|
329 |
|
21195
9336bc7dca8e
cmdserver: forcibly use L channel to read password input (issue3161)
Yuya Nishihara <yuya@tcha.org>
parents:
20650
diff
changeset
|
330 |
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
|
331 |
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
|
332 |
# 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
|
333 |
# 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
|
334 |
# 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
|
335 |
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
|
336 |
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
|
337 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
338 |
req = dispatch.request( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
339 |
args[:], |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
340 |
copiedui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
341 |
self.repo, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
342 |
self.cin, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
343 |
self.cout, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
344 |
self.cerr, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
345 |
self.cmsg, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
346 |
prereposetups=self._prereposetups, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
347 |
) |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
348 |
|
35652
40da2d7b4871
commandserver: restore cwd in case of exception
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35461
diff
changeset
|
349 |
try: |
46101
49b6910217f9
dispatch: move IOError handling and flushing of streams to `dispatch()`
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46086
diff
changeset
|
350 |
ret = self._dispatchcommand(req) & 255 |
45057
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
351 |
# If shutdown-on-interrupt is off, it's important to write the |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
352 |
# result code *after* SIGINT handler removed. If the result code |
d6e99a446eea
cmdserver: add option to not exit from message loop on SIGINT
Yuya Nishihara <yuya@tcha.org>
parents:
44374
diff
changeset
|
353 |
# were lost, the client wouldn't be able to continue processing. |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
354 |
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
|
355 |
finally: |
40da2d7b4871
commandserver: restore cwd in case of exception
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35461
diff
changeset
|
356 |
# restore old cwd |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
357 |
if b'--cwd' in args: |
35652
40da2d7b4871
commandserver: restore cwd in case of exception
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35461
diff
changeset
|
358 |
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
|
359 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
360 |
def getencoding(self): |
47062
f38bf44e077f
black: make codebase compatible with black v21.4b2 and v20.8b1
Kyle Lippincott <spectral@google.com>
parents:
46819
diff
changeset
|
361 |
"""writes the current encoding to the result channel""" |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
362 |
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
|
363 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
364 |
def serveone(self): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
365 |
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
|
366 |
if cmd: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
367 |
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
|
368 |
if handler: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
369 |
handler(self) |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
370 |
else: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
371 |
# 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
|
372 |
# looking at the servers capabilities |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
373 |
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
|
374 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
375 |
return cmd != b'' |
14647
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
376 |
|
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
377 |
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
|
378 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
379 |
def serve(self): |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
380 |
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
|
381 |
hellomsg += b'\n' |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
382 |
hellomsg += b'encoding: ' + encoding.encoding |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
383 |
hellomsg += b'\n' |
40589
054d0fcba2c4
commandserver: add experimental option to use separate message channel
Yuya Nishihara <yuya@tcha.org>
parents:
40588
diff
changeset
|
384 |
if self.cmsg: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
385 |
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
|
386 |
hellomsg += b'pid: %d' % procutil.getpid() |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
387 |
if util.safehasattr(os, b'getpgid'): |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
388 |
hellomsg += b'\n' |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
389 |
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
|
390 |
|
c19de7f32961
cmdserver: write the hello message as one chunk on the 'o' channel
Idan Kamara <idankk86@gmail.com>
parents:
14707
diff
changeset
|
391 |
# 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
|
392 |
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
|
393 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
394 |
try: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
395 |
while self.serveone(): |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
396 |
pass |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
397 |
except EOFError: |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
398 |
# 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
|
399 |
# its request |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
400 |
return 1 |
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
401 |
|
2e9f379de0ac
serve: add --cmdserver option to communicate with hg over a pipe
Idan Kamara <idankk86@gmail.com>
parents:
diff
changeset
|
402 |
return 0 |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
403 |
|
43076
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 |
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
|
406 |
"""Set up server logging facility |
368ecbf734af
commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents:
40819
diff
changeset
|
407 |
|
40824
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
408 |
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
|
409 |
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
|
410 |
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
|
411 |
""" |
368ecbf734af
commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents:
40819
diff
changeset
|
412 |
# developer config: cmdserver.log |
368ecbf734af
commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents:
40819
diff
changeset
|
413 |
logpath = ui.config(b'cmdserver', b'log') |
368ecbf734af
commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents:
40819
diff
changeset
|
414 |
if not logpath: |
368ecbf734af
commandserver: enable logging when server process started
Yuya Nishihara <yuya@tcha.org>
parents:
40819
diff
changeset
|
415 |
return |
40827
d23fd01cc115
commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents:
40826
diff
changeset
|
416 |
# developer config: cmdserver.track-log |
d23fd01cc115
commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents:
40826
diff
changeset
|
417 |
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
|
418 |
|
40824
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
419 |
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
|
420 |
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
|
421 |
elif logpath == b'-': |
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
422 |
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
|
423 |
else: |
47624
27e75b8bf784
windows: use abspath in commandserver
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
47062
diff
changeset
|
424 |
logpath = util.abspath(util.expandpath(logpath)) |
40827
d23fd01cc115
commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents:
40826
diff
changeset
|
425 |
# developer config: cmdserver.max-log-files |
d23fd01cc115
commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents:
40826
diff
changeset
|
426 |
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
|
427 |
# developer config: cmdserver.max-log-size |
d23fd01cc115
commandserver: add config knob for various logging options
Yuya Nishihara <yuya@tcha.org>
parents:
40826
diff
changeset
|
428 |
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
|
429 |
vfs = vfsmod.vfs(os.path.dirname(logpath)) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
430 |
logger = loggingutil.filelogger( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
431 |
vfs, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
432 |
os.path.basename(logpath), |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
433 |
tracked, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
434 |
maxfiles=maxfiles, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
435 |
maxsize=maxsize, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
436 |
) |
40824
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
437 |
|
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
438 |
targetuis = {ui} |
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
439 |
if repo: |
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
440 |
targetuis.add(repo.baseui) |
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
441 |
targetuis.add(repo.ui) |
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
442 |
for u in targetuis: |
82210d88d814
commandserver: install logger to record server events through canonical API
Yuya Nishihara <yuya@tcha.org>
parents:
40823
diff
changeset
|
443 |
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
|
444 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
445 |
|
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
446 |
class pipeservice: |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
447 |
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
|
448 |
self.ui = ui |
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
449 |
self.repo = repo |
22988
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
450 |
|
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
451 |
def init(self): |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
452 |
pass |
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
453 |
|
32b77aba2772
cmdserver: wrap 'pipe' mode server by service object
Yuya Nishihara <yuya@tcha.org>
parents:
22563
diff
changeset
|
454 |
def run(self): |
23323
bc374458688b
cmdserver: postpone creation of pipe server until run()
Yuya Nishihara <yuya@tcha.org>
parents:
23322
diff
changeset
|
455 |
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
|
456 |
# 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
|
457 |
# 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
|
458 |
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
|
459 |
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
|
460 |
try: |
6715e8035b4f
procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents:
37123
diff
changeset
|
461 |
return sv.serve() |
6715e8035b4f
procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents:
37123
diff
changeset
|
462 |
finally: |
6715e8035b4f
procutil: introduce context-manager interface for protect/restorestdio
Yuya Nishihara <yuya@tcha.org>
parents:
37123
diff
changeset
|
463 |
sv.cleanup() |
22989
dc8803ce3dfe
cmdserver: switch service objects by mode
Yuya Nishihara <yuya@tcha.org>
parents:
22988
diff
changeset
|
464 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
465 |
|
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
466 |
def _initworkerprocess(): |
29609
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
467 |
# 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
|
468 |
# 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
|
469 |
# 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
|
470 |
# remains in a same session) |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
471 |
# 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
|
472 |
# 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
|
473 |
# cause trouble for things like ncurses. |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
474 |
# 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
|
475 |
# 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
|
476 |
# processes like ssh will be killed properly, without affecting |
591c3badff2e
commandserver: update comment about setpgid
Jun Wu <quark@fb.com>
parents:
29588
diff
changeset
|
477 |
# unrelated processes. |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
478 |
os.setpgid(0, 0) |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
479 |
# 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
|
480 |
# same state inherited from parent. |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
481 |
random.seed() |
29542
6011ad3b0a42
commandserver: manually create file objects from socket
Yuya Nishihara <yuya@tcha.org>
parents:
29532
diff
changeset
|
482 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
483 |
|
40875
e7110f44ee2d
commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents:
40828
diff
changeset
|
484 |
def _serverequest(ui, repo, conn, createcmdserver, prereposetups): |
43506
9f70512ae2cf
cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents:
43089
diff
changeset
|
485 |
fin = conn.makefile('rb') |
9f70512ae2cf
cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents:
43089
diff
changeset
|
486 |
fout = conn.makefile('wb') |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
487 |
sv = None |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
488 |
try: |
40875
e7110f44ee2d
commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents:
40828
diff
changeset
|
489 |
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
|
490 |
try: |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
491 |
sv.serve() |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
492 |
# 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
|
493 |
# known exceptions are caught by dispatch. |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
494 |
except error.Abort as inst: |
45682
d2e1dcd4490d
errors: name arguments to Abort constructor
Martin von Zweigbergk <martinvonz@google.com>
parents:
45058
diff
changeset
|
495 |
ui.error(_(b'abort: %s\n') % inst.message) |
49304
48f1b314056b
py3: catch BrokenPipeError instead of checking errno == EPIPE
Manuel Jacob <me@manueljacob.de>
parents:
49303
diff
changeset
|
496 |
except BrokenPipeError: |
48f1b314056b
py3: catch BrokenPipeError instead of checking errno == EPIPE
Manuel Jacob <me@manueljacob.de>
parents:
49303
diff
changeset
|
497 |
pass |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
498 |
except KeyboardInterrupt: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
499 |
pass |
29513
e5b4d79a9140
commandserver: backport handling of forking server from chgserver
Yuya Nishihara <yuya@tcha.org>
parents:
29512
diff
changeset
|
500 |
finally: |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
501 |
sv.cleanup() |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
502 |
except: # re-raises |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
503 |
# 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
|
504 |
# 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
|
505 |
if sv: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
506 |
cerr = sv.cerr |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
507 |
else: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
508 |
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
|
509 |
cerr.write(encoding.strtolocal(traceback.format_exc())) |
29585
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
510 |
raise |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
511 |
finally: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
512 |
fin.close() |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
513 |
try: |
6ed452d0f1f1
commandserver: unindent superfluous "if True" blocks
Yuya Nishihara <yuya@tcha.org>
parents:
29580
diff
changeset
|
514 |
fout.close() # implicit flush() may cause another EPIPE |
49304
48f1b314056b
py3: catch BrokenPipeError instead of checking errno == EPIPE
Manuel Jacob <me@manueljacob.de>
parents:
49303
diff
changeset
|
515 |
except BrokenPipeError: |
48f1b314056b
py3: catch BrokenPipeError instead of checking errno == EPIPE
Manuel Jacob <me@manueljacob.de>
parents:
49303
diff
changeset
|
516 |
pass |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
517 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
518 |
|
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
519 |
class unixservicehandler: |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
520 |
"""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
|
521 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
522 |
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
|
523 |
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
|
524 |
""" |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
525 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
526 |
pollinterval = None |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
527 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
528 |
def __init__(self, ui): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
529 |
self.ui = ui |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
530 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
531 |
def bindsocket(self, sock, address): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
532 |
util.bindunixsocket(sock, address) |
32236
c8b9943c07eb
commandserver: move "listen" responsibility from service to handler
Jun Wu <quark@fb.com>
parents:
30924
diff
changeset
|
533 |
sock.listen(socket.SOMAXCONN) |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
534 |
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
|
535 |
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
|
536 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
537 |
def unlinksocket(self, address): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
538 |
os.unlink(address) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
539 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
540 |
def shouldexit(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
541 |
"""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
|
542 |
return False |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
543 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
544 |
def newconnection(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
545 |
"""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
|
546 |
|
40875
e7110f44ee2d
commandserver: pass around option to hook repo instance creation
Yuya Nishihara <yuya@tcha.org>
parents:
40828
diff
changeset
|
547 |
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
|
548 |
"""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
|
549 |
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
|
550 |
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
|
551 |
|
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
552 |
|
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
553 |
class unixforkingservice: |
22994
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
554 |
""" |
840be5ca03e1
cmdserver: add service that listens on unix domain socket and forks process
Yuya Nishihara <yuya@tcha.org>
parents:
22990
diff
changeset
|
555 |
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
|
556 |
""" |
29548
9da1adc18639
commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents:
29544
diff
changeset
|
557 |
|
9da1adc18639
commandserver: drop old unixservice implementation
Yuya Nishihara <yuya@tcha.org>
parents:
29544
diff
changeset
|
558 |
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
|
559 |
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
|
560 |
self.repo = repo |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
561 |
self.address = opts[b'address'] |
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
562 |
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
|
563 |
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
|
564 |
if not self.address: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
565 |
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
|
566 |
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
|
567 |
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
|
568 |
self._mainipc = None |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
569 |
self._workeripc = None |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
570 |
self._oldsigchldhandler = None |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
571 |
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
|
572 |
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
|
573 |
# 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
|
574 |
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
|
575 |
if maxlen < 0: |
43077
687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents:
43076
diff
changeset
|
576 |
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
|
577 |
self._repoloader = repocache.repoloader(ui, maxlen) |
44368
6392bd7c26a8
darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents:
43506
diff
changeset
|
578 |
# attempt to avoid crash in CoreFoundation when using chg after fix in |
6392bd7c26a8
darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents:
43506
diff
changeset
|
579 |
# a89381e04c58 |
6392bd7c26a8
darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents:
43506
diff
changeset
|
580 |
if pycompat.isdarwin: |
6392bd7c26a8
darwin: add another preemptive gui() call when using chg
Kyle Lippincott <spectral@google.com>
parents:
43506
diff
changeset
|
581 |
procutil.gui() |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
582 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
583 |
def init(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
584 |
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
|
585 |
# 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
|
586 |
# 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
|
587 |
# 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
|
588 |
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
|
589 |
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
|
590 |
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
|
591 |
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
|
592 |
procutil.unblocksignal(signal.SIGCHLD) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
593 |
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
|
594 |
self._oldsigchldhandler = o |
30887
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
595 |
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
|
596 |
self._repoloader.start() |
30887
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
597 |
|
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
598 |
def _unlinksocket(self): |
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
599 |
if not self._socketunlinked: |
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
600 |
self._servicehandler.unlinksocket(self.address) |
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
601 |
self._socketunlinked = True |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
602 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
603 |
def _cleanup(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
604 |
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
|
605 |
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
|
606 |
self._mainipc.close() |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
607 |
self._workeripc.close() |
30887
a95fc01aaffe
commandserver: prevent unlink socket twice
Jun Wu <quark@fb.com>
parents:
30519
diff
changeset
|
608 |
self._unlinksocket() |
40999
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
609 |
self._repoloader.stop() |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
610 |
# 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
|
611 |
self._reapworkers(0) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
612 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
613 |
def run(self): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
614 |
try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
615 |
self._mainloop() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
616 |
finally: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
617 |
self._cleanup() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
618 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
619 |
def _mainloop(self): |
30891
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
620 |
exiting = False |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
621 |
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
|
622 |
selector = selectors.DefaultSelector() |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
623 |
selector.register( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
624 |
self._sock, selectors.EVENT_READ, self._acceptnewconnection |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
625 |
) |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
626 |
selector.register( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
627 |
self._mainipc, selectors.EVENT_READ, self._handlemainipc |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
628 |
) |
30891
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
629 |
while True: |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
630 |
if not exiting and h.shouldexit(): |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
631 |
# 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
|
632 |
# we stop queuing new requests. |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
633 |
# 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
|
634 |
# accept()-ed), handle them before exit. otherwise, clients |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
635 |
# waiting for recv() will receive ECONNRESET. |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
636 |
self._unlinksocket() |
b1b36c6499c2
commandserver: handle backlog before exiting
Jun Wu <quark@fb.com>
parents:
30887
diff
changeset
|
637 |
exiting = True |
49280
311fcc5a65f6
thirdparty: remove Python 2-specific selectors2 copy
Manuel Jacob <me@manueljacob.de>
parents:
48946
diff
changeset
|
638 |
events = selector.select(timeout=h.pollinterval) |
40878
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
639 |
if not events: |
33543
3ef3bf704e47
commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents:
33506
diff
changeset
|
640 |
# 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
|
641 |
if exiting: |
3ef3bf704e47
commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents:
33506
diff
changeset
|
642 |
break |
3ef3bf704e47
commandserver: do not handle EINTR for selector.select
Jun Wu <quark@fb.com>
parents:
33506
diff
changeset
|
643 |
continue |
40878
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
644 |
for key, _mask in events: |
2525faf4ecdb
commandserver: loop over selector events
Yuya Nishihara <yuya@tcha.org>
parents:
40877
diff
changeset
|
645 |
key.data(key.fileobj, selector) |
40876
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
646 |
selector.close() |
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
647 |
|
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
648 |
def _acceptnewconnection(self, sock, selector): |
dc9901558e3c
commandserver: extract handler of new socket connection
Yuya Nishihara <yuya@tcha.org>
parents:
40875
diff
changeset
|
649 |
h = self._servicehandler |
49302
ee4537e365c8
py3: remove retry on EINTR errno
Manuel Jacob <me@manueljacob.de>
parents:
49280
diff
changeset
|
650 |
conn, _addr = sock.accept() |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
651 |
|
40999
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
652 |
# 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
|
653 |
# 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
|
654 |
# 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
|
655 |
# 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
|
656 |
pid = os.fork() |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
657 |
if pid: |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
658 |
try: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
659 |
self.ui.log( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
660 |
b'cmdserver', b'forked worker process (pid=%d)\n', pid |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
661 |
) |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
662 |
self._workerpids.add(pid) |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
663 |
h.newconnection() |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
664 |
finally: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
665 |
conn.close() # release handle in parent process |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
666 |
else: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
667 |
try: |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
668 |
selector.close() |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
669 |
sock.close() |
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
670 |
self._mainipc.close() |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
671 |
self._runworker(conn) |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
672 |
conn.close() |
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
673 |
self._workeripc.close() |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
674 |
os._exit(0) |
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
675 |
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
|
676 |
try: |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
677 |
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
|
678 |
finally: |
40877
9f00de4dc7cb
commandserver: remove redundant "if True" block
Yuya Nishihara <yuya@tcha.org>
parents:
40876
diff
changeset
|
679 |
os._exit(255) |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
680 |
|
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
681 |
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
|
682 |
"""Process messages sent from a worker""" |
49302
ee4537e365c8
py3: remove retry on EINTR errno
Manuel Jacob <me@manueljacob.de>
parents:
49280
diff
changeset
|
683 |
path = sock.recv(32768) # large enough to receive path |
40999
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
684 |
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
|
685 |
|
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
686 |
def _sigchldhandler(self, signal, frame): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
687 |
self._reapworkers(os.WNOHANG) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
688 |
|
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
689 |
def _reapworkers(self, options): |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
690 |
while self._workerpids: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
691 |
try: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
692 |
pid, _status = os.waitpid(-1, options) |
49303
dfdf85f37215
py3: catch ChildProcessError instead of checking errno == ECHILD
Manuel Jacob <me@manueljacob.de>
parents:
49302
diff
changeset
|
693 |
except ChildProcessError: |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
694 |
# 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
|
695 |
self._workerpids.clear() |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
696 |
return |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
697 |
if pid == 0: |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
698 |
# no waitable child processes |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
699 |
return |
40828
25e9089c7686
commandserver: turn server debug messages into logs
Yuya Nishihara <yuya@tcha.org>
parents:
40827
diff
changeset
|
700 |
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
|
701 |
self._workerpids.discard(pid) |
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
702 |
|
29587
536eec443b4a
commandserver: rename _serveworker() to _runworker()
Yuya Nishihara <yuya@tcha.org>
parents:
29586
diff
changeset
|
703 |
def _runworker(self, conn): |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
704 |
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
|
705 |
_initworkerprocess() |
29544
024e8f82f3de
commandserver: add new forking server implemented without using SocketServer
Yuya Nishihara <yuya@tcha.org>
parents:
29543
diff
changeset
|
706 |
h = self._servicehandler |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
707 |
try: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
708 |
_serverequest( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
709 |
self.ui, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
710 |
self.repo, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
711 |
conn, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
712 |
h.createcmdserver, |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
713 |
prereposetups=[self._reposetup], |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
714 |
) |
29586
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
715 |
finally: |
42cdba9cfee4
commandserver: separate initialization and cleanup of forked process
Yuya Nishihara <yuya@tcha.org>
parents:
29585
diff
changeset
|
716 |
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
|
717 |
|
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
718 |
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
|
719 |
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
|
720 |
return |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
721 |
|
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
722 |
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
|
723 |
def close(self): |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
724 |
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
|
725 |
try: |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
726 |
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
|
727 |
except socket.error: |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
728 |
self.ui.log( |
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
41284
diff
changeset
|
729 |
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
|
730 |
) |
40998
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
731 |
|
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
732 |
repo.__class__ = unixcmdserverrepo |
042ed354b9eb
commandserver: add IPC channel to teach repository path on command finished
Yuya Nishihara <yuya@tcha.org>
parents:
40878
diff
changeset
|
733 |
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
|
734 |
|
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
735 |
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
|
736 |
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
|
737 |
return |
dcac24ec935b
commandserver: preload repository in master server and reuse its file cache
Yuya Nishihara <yuya@tcha.org>
parents:
40998
diff
changeset
|
738 |
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
|
739 |
repocache.copycache(cachedrepo, repo) |