annotate mercurial/commandserver.py @ 49037:642e31cb55f0

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