##// END OF EJS Templates
Removed ANSI coloring for kernel exception hook.
epatters -
Show More
@@ -1,201 +1,199 b''
1 1 """ Defines helper functions for creating kernel entry points and process
2 2 launchers.
3 3 """
4 4
5 5 # Standard library imports.
6 6 import os
7 7 import socket
8 8 from subprocess import Popen
9 9 import sys
10 10
11 11 # System library imports.
12 12 import zmq
13 13
14 14 # Local imports.
15 15 from IPython.core.ultratb import FormattedTB
16 16 from IPython.external.argparse import ArgumentParser
17 17 from IPython.utils import io
18 18 from exitpoller import ExitPollerUnix, ExitPollerWindows
19 19 from displayhook import DisplayHook
20 20 from iostream import OutStream
21 21 from session import Session
22 22
23 23
24 24 def bind_port(socket, ip, port):
25 25 """ Binds the specified ZMQ socket. If the port is zero, a random port is
26 26 chosen. Returns the port that was bound.
27 27 """
28 28 connection = 'tcp://%s' % ip
29 29 if port <= 0:
30 30 port = socket.bind_to_random_port(connection)
31 31 else:
32 32 connection += ':%i' % port
33 33 socket.bind(connection)
34 34 return port
35 35
36 36
37 37 def make_argument_parser():
38 38 """ Creates an ArgumentParser for the generic arguments supported by all
39 39 kernel entry points.
40 40 """
41 41 parser = ArgumentParser()
42 42 parser.add_argument('--ip', type=str, default='127.0.0.1',
43 43 help='set the kernel\'s IP address [default: local]')
44 44 parser.add_argument('--xrep', type=int, metavar='PORT', default=0,
45 45 help='set the XREP channel port [default: random]')
46 46 parser.add_argument('--pub', type=int, metavar='PORT', default=0,
47 47 help='set the PUB channel port [default: random]')
48 48 parser.add_argument('--req', type=int, metavar='PORT', default=0,
49 49 help='set the REQ channel port [default: random]')
50 50
51 51 if sys.platform == 'win32':
52 52 parser.add_argument('--parent', type=int, metavar='HANDLE',
53 53 default=0, help='kill this process if the process '
54 54 'with HANDLE dies')
55 55 else:
56 56 parser.add_argument('--parent', action='store_true',
57 57 help='kill this process if its parent dies')
58 58
59 59 return parser
60 60
61 61
62 62 def make_kernel(namespace, kernel_factory,
63 63 out_stream_factory=None, display_hook_factory=None):
64 64 """ Creates a kernel.
65 65 """
66 66 # Install minimal exception handling
67 color_scheme = 'LightBG' if sys.platform == 'darwin' else 'Linux'
68 sys.excepthook = FormattedTB(
69 mode='Verbose', color_scheme=color_scheme, ostream=sys.__stdout__
70 )
67 sys.excepthook = FormattedTB(mode='Verbose', color_scheme='NoColor',
68 ostream=sys.__stdout__)
71 69
72 70 # Create a context, a session, and the kernel sockets.
73 71 io.raw_print("Starting the kernel...")
74 72 context = zmq.Context()
75 73 session = Session(username=u'kernel')
76 74
77 75 reply_socket = context.socket(zmq.XREP)
78 76 xrep_port = bind_port(reply_socket, namespace.ip, namespace.xrep)
79 77 io.raw_print("XREP Channel on port", xrep_port)
80 78
81 79 pub_socket = context.socket(zmq.PUB)
82 80 pub_port = bind_port(pub_socket, namespace.ip, namespace.pub)
83 81 io.raw_print("PUB Channel on port", pub_port)
84 82
85 83 req_socket = context.socket(zmq.XREQ)
86 84 req_port = bind_port(req_socket, namespace.ip, namespace.req)
87 85 io.raw_print("REQ Channel on port", req_port)
88 86
89 87 # Redirect input streams and set a display hook.
90 88 if out_stream_factory:
91 89 pass
92 90 sys.stdout = out_stream_factory(session, pub_socket, u'stdout')
93 91 sys.stderr = out_stream_factory(session, pub_socket, u'stderr')
94 92 if display_hook_factory:
95 93 sys.displayhook = display_hook_factory(session, pub_socket)
96 94
97 95 # Create the kernel.
98 96 return kernel_factory(session=session, reply_socket=reply_socket,
99 97 pub_socket=pub_socket, req_socket=req_socket)
100 98
101 99
102 100 def start_kernel(namespace, kernel):
103 101 """ Starts a kernel.
104 102 """
105 103 # Configure this kernel/process to die on parent termination, if necessary.
106 104 if namespace.parent:
107 105 if sys.platform == 'win32':
108 106 poller = ExitPollerWindows(namespace.parent)
109 107 else:
110 108 poller = ExitPollerUnix()
111 109 poller.start()
112 110
113 111 # Start the kernel mainloop.
114 112 kernel.start()
115 113
116 114
117 115 def make_default_main(kernel_factory):
118 116 """ Creates the simplest possible kernel entry point.
119 117 """
120 118 def main():
121 119 namespace = make_argument_parser().parse_args()
122 120 kernel = make_kernel(namespace, kernel_factory, OutStream, DisplayHook)
123 121 start_kernel(namespace, kernel)
124 122 return main
125 123
126 124
127 125 def base_launch_kernel(code, xrep_port=0, pub_port=0, req_port=0,
128 126 independent=False, extra_arguments=[]):
129 127 """ Launches a localhost kernel, binding to the specified ports.
130 128
131 129 Parameters
132 130 ----------
133 131 code : str,
134 132 A string of Python code that imports and executes a kernel entry point.
135 133
136 134 xrep_port : int, optional
137 135 The port to use for XREP channel.
138 136
139 137 pub_port : int, optional
140 138 The port to use for the SUB channel.
141 139
142 140 req_port : int, optional
143 141 The port to use for the REQ (raw input) channel.
144 142
145 143 independent : bool, optional (default False)
146 144 If set, the kernel process is guaranteed to survive if this process
147 145 dies. If not set, an effort is made to ensure that the kernel is killed
148 146 when this process dies. Note that in this case it is still good practice
149 147 to kill kernels manually before exiting.
150 148
151 149 extra_arguments = list, optional
152 150 A list of extra arguments to pass when executing the launch code.
153 151
154 152 Returns
155 153 -------
156 154 A tuple of form:
157 155 (kernel_process, xrep_port, pub_port, req_port)
158 156 where kernel_process is a Popen object and the ports are integers.
159 157 """
160 158 # Find open ports as necessary.
161 159 ports = []
162 160 ports_needed = int(xrep_port <= 0) + int(pub_port <= 0) + int(req_port <= 0)
163 161 for i in xrange(ports_needed):
164 162 sock = socket.socket()
165 163 sock.bind(('', 0))
166 164 ports.append(sock)
167 165 for i, sock in enumerate(ports):
168 166 port = sock.getsockname()[1]
169 167 sock.close()
170 168 ports[i] = port
171 169 if xrep_port <= 0:
172 170 xrep_port = ports.pop(0)
173 171 if pub_port <= 0:
174 172 pub_port = ports.pop(0)
175 173 if req_port <= 0:
176 174 req_port = ports.pop(0)
177 175
178 176 # Build the kernel launch command.
179 177 arguments = [ sys.executable, '-c', code, '--xrep', str(xrep_port),
180 178 '--pub', str(pub_port), '--req', str(req_port) ]
181 179 arguments.extend(extra_arguments)
182 180
183 181 # Spawn a kernel.
184 182 if independent:
185 183 if sys.platform == 'win32':
186 184 proc = Popen(['start', '/b'] + arguments, shell=True)
187 185 else:
188 186 proc = Popen(arguments, preexec_fn=lambda: os.setsid())
189 187 else:
190 188 if sys.platform == 'win32':
191 189 from _subprocess import DuplicateHandle, GetCurrentProcess, \
192 190 DUPLICATE_SAME_ACCESS
193 191 pid = GetCurrentProcess()
194 192 handle = DuplicateHandle(pid, pid, pid, 0,
195 193 True, # Inheritable by new processes.
196 194 DUPLICATE_SAME_ACCESS)
197 195 proc = Popen(arguments + ['--parent', str(int(handle))])
198 196 else:
199 197 proc = Popen(arguments + ['--parent'])
200 198
201 199 return proc, xrep_port, pub_port, req_port
General Comments 0
You need to be logged in to leave comments. Login now