Show More
@@ -330,7 +330,7 b' class MainKernelHandler(AuthenticatedHandler):' | |||||
330 | @web.authenticated |
|
330 | @web.authenticated | |
331 | def get(self): |
|
331 | def get(self): | |
332 | km = self.application.kernel_manager |
|
332 | km = self.application.kernel_manager | |
333 | self.finish(jsonapi.dumps(km.kernel_ids)) |
|
333 | self.finish(jsonapi.dumps(km.list_kernel_ids())) | |
334 |
|
334 | |||
335 | @web.authenticated |
|
335 | @web.authenticated | |
336 | def post(self): |
|
336 | def post(self): |
@@ -63,20 +63,18 b' class MultiKernelManager(LoggingConfigurable):' | |||||
63 |
|
63 | |||
64 | _kernels = Dict() |
|
64 | _kernels = Dict() | |
65 |
|
65 | |||
66 | @property |
|
66 | def list_kernel_ids(self): | |
67 | def kernel_ids(self): |
|
|||
68 | """Return a list of the kernel ids of the active kernels.""" |
|
67 | """Return a list of the kernel ids of the active kernels.""" | |
69 | return self._kernels.keys() |
|
68 | # Create a copy so we can iterate over kernels in operations | |
|
69 | # that delete keys. | |||
|
70 | return list(self._kernels.keys()) | |||
70 |
|
71 | |||
71 | def __len__(self): |
|
72 | def __len__(self): | |
72 | """Return the number of running kernels.""" |
|
73 | """Return the number of running kernels.""" | |
73 | return len(self.kernel_ids) |
|
74 | return len(self.list_kernel_ids()) | |
74 |
|
75 | |||
75 | def __contains__(self, kernel_id): |
|
76 | def __contains__(self, kernel_id): | |
76 |
|
|
77 | return kernel_id in self._kernels | |
77 | return True |
|
|||
78 | else: |
|
|||
79 | return False |
|
|||
80 |
|
78 | |||
81 | def start_kernel(self, **kwargs): |
|
79 | def start_kernel(self, **kwargs): | |
82 | """Start a new kernel. |
|
80 | """Start a new kernel. | |
@@ -109,6 +107,11 b' class MultiKernelManager(LoggingConfigurable):' | |||||
109 | self.get_kernel(kernel_id).shutdown_kernel() |
|
107 | self.get_kernel(kernel_id).shutdown_kernel() | |
110 | del self._kernels[kernel_id] |
|
108 | del self._kernels[kernel_id] | |
111 |
|
109 | |||
|
110 | def shutdown_all(self): | |||
|
111 | """Shutdown all kernels.""" | |||
|
112 | for kid in self.list_kernel_ids(): | |||
|
113 | self.shutdown_kernel(kid) | |||
|
114 | ||||
112 | def kill_kernel(self, kernel_id): |
|
115 | def kill_kernel(self, kernel_id): | |
113 | """Kill a kernel by its kernel uuid. |
|
116 | """Kill a kernel by its kernel uuid. | |
114 |
|
117 | |||
@@ -120,6 +123,11 b' class MultiKernelManager(LoggingConfigurable):' | |||||
120 | self.get_kernel(kernel_id).kill_kernel() |
|
123 | self.get_kernel(kernel_id).kill_kernel() | |
121 | del self._kernels[kernel_id] |
|
124 | del self._kernels[kernel_id] | |
122 |
|
125 | |||
|
126 | def kill_all(self): | |||
|
127 | """Kill all kernels.""" | |||
|
128 | for kid in self.list_kernel_ids(): | |||
|
129 | self.kill_kernel(kid) | |||
|
130 | ||||
123 | def interrupt_kernel(self, kernel_id): |
|
131 | def interrupt_kernel(self, kernel_id): | |
124 | """Interrupt (SIGINT) the kernel by its uuid. |
|
132 | """Interrupt (SIGINT) the kernel by its uuid. | |
125 |
|
133 | |||
@@ -167,8 +175,8 b' class MultiKernelManager(LoggingConfigurable):' | |||||
167 | else: |
|
175 | else: | |
168 | raise KeyError("Kernel with id not found: %s" % kernel_id) |
|
176 | raise KeyError("Kernel with id not found: %s" % kernel_id) | |
169 |
|
177 | |||
170 |
def get_ |
|
178 | def get_connection_data(self, kernel_id): | |
171 |
"""Return a dictionary of |
|
179 | """Return a dictionary of connection data for a kernel. | |
172 |
|
180 | |||
173 | Parameters |
|
181 | Parameters | |
174 | ========== |
|
182 | ========== | |
@@ -177,21 +185,29 b' class MultiKernelManager(LoggingConfigurable):' | |||||
177 |
|
185 | |||
178 | Returns |
|
186 | Returns | |
179 | ======= |
|
187 | ======= | |
180 |
|
|
188 | connection_dict : dict | |
181 | A dict of key, value pairs where the keys are the names |
|
189 | A dict of the information needed to connect to a kernel. | |
182 | (stdin_port,iopub_port,shell_port) and the values are the |
|
190 | This includes the ip address and the integer port | |
183 | integer port numbers for those channels. |
|
191 | numbers of the different channels (stdin_port, iopub_port, | |
|
192 | shell_port, hb_port). | |||
184 | """ |
|
193 | """ | |
185 | # this will raise a KeyError if not found: |
|
|||
186 | km = self.get_kernel(kernel_id) |
|
194 | km = self.get_kernel(kernel_id) | |
187 |
return dict( |
|
195 | return dict(ip=km.ip, | |
|
196 | shell_port=km.shell_port, | |||
188 | iopub_port=km.iopub_port, |
|
197 | iopub_port=km.iopub_port, | |
189 | stdin_port=km.stdin_port, |
|
198 | stdin_port=km.stdin_port, | |
190 | hb_port=km.hb_port, |
|
199 | hb_port=km.hb_port, | |
191 | ) |
|
200 | ) | |
192 |
|
201 | |||
193 | def get_kernel_ip(self, kernel_id): |
|
202 | def create_connected_stream(self, ip, port, socket_type): | |
194 | """Return ip address for a kernel. |
|
203 | sock = self.context.socket(socket_type) | |
|
204 | addr = "tcp://%s:%i" % (ip, port) | |||
|
205 | self.log.info("Connecting to: %s" % addr) | |||
|
206 | sock.connect(addr) | |||
|
207 | return ZMQStream(sock) | |||
|
208 | ||||
|
209 | def create_iopub_stream(self, kernel_id): | |||
|
210 | """Return a ZMQStream object connected to the iopub channel. | |||
195 |
|
211 | |||
196 | Parameters |
|
212 | Parameters | |
197 | ========== |
|
213 | ========== | |
@@ -200,35 +216,49 b' class MultiKernelManager(LoggingConfigurable):' | |||||
200 |
|
216 | |||
201 | Returns |
|
217 | Returns | |
202 | ======= |
|
218 | ======= | |
203 |
|
|
219 | stream : ZMQStream | |
204 | The ip address of the kernel. |
|
|||
205 | """ |
|
220 | """ | |
206 |
|
|
221 | kdata = self.get_connection_data(kernel_id) | |
207 |
|
222 | iopub_stream = self.create_connected_stream( | ||
208 | def create_connected_stream(self, ip, port, socket_type): |
|
223 | kdata['ip'], kdata['iopub_port'], zmq.SUB | |
209 | sock = self.context.socket(socket_type) |
|
224 | ) | |
210 | addr = "tcp://%s:%i" % (ip, port) |
|
|||
211 | self.log.info("Connecting to: %s" % addr) |
|
|||
212 | sock.connect(addr) |
|
|||
213 | return ZMQStream(sock) |
|
|||
214 |
|
||||
215 | def create_iopub_stream(self, kernel_id): |
|
|||
216 | ip = self.get_kernel_ip(kernel_id) |
|
|||
217 | ports = self.get_kernel_ports(kernel_id) |
|
|||
218 | iopub_stream = self.create_connected_stream(ip, ports['iopub_port'], zmq.SUB) |
|
|||
219 | iopub_stream.socket.setsockopt(zmq.SUBSCRIBE, b'') |
|
225 | iopub_stream.socket.setsockopt(zmq.SUBSCRIBE, b'') | |
220 | return iopub_stream |
|
226 | return iopub_stream | |
221 |
|
227 | |||
222 | def create_shell_stream(self, kernel_id): |
|
228 | def create_shell_stream(self, kernel_id): | |
223 | ip = self.get_kernel_ip(kernel_id) |
|
229 | """Return a ZMQStream object connected to the shell channel. | |
224 | ports = self.get_kernel_ports(kernel_id) |
|
230 | ||
225 | shell_stream = self.create_connected_stream(ip, ports['shell_port'], zmq.DEALER) |
|
231 | Parameters | |
|
232 | ========== | |||
|
233 | kernel_id : uuid | |||
|
234 | The id of the kernel. | |||
|
235 | ||||
|
236 | Returns | |||
|
237 | ======= | |||
|
238 | stream : ZMQStream | |||
|
239 | """ | |||
|
240 | kdata = self.get_connection_data(kernel_id) | |||
|
241 | shell_stream = self.create_connected_stream( | |||
|
242 | kdata['ip'], kdata['shell_port'], zmq.DEALER | |||
|
243 | ) | |||
226 | return shell_stream |
|
244 | return shell_stream | |
227 |
|
245 | |||
228 | def create_hb_stream(self, kernel_id): |
|
246 | def create_hb_stream(self, kernel_id): | |
229 | ip = self.get_kernel_ip(kernel_id) |
|
247 | """Return a ZMQStream object connected to the hb channel. | |
230 | ports = self.get_kernel_ports(kernel_id) |
|
248 | ||
231 | hb_stream = self.create_connected_stream(ip, ports['hb_port'], zmq.REQ) |
|
249 | Parameters | |
|
250 | ========== | |||
|
251 | kernel_id : uuid | |||
|
252 | The id of the kernel. | |||
|
253 | ||||
|
254 | Returns | |||
|
255 | ======= | |||
|
256 | stream : ZMQStream | |||
|
257 | """ | |||
|
258 | kdata = self.get_connection_data(kernel_id) | |||
|
259 | hb_stream = self.create_connected_stream( | |||
|
260 | kdata['ip'], kdata['hb_port'], zmq.REQ | |||
|
261 | ) | |||
232 | return hb_stream |
|
262 | return hb_stream | |
233 |
|
263 | |||
234 |
|
264 |
@@ -591,16 +591,13 b' class NotebookApp(BaseIPythonApplication):' | |||||
591 | self.init_signal() |
|
591 | self.init_signal() | |
592 |
|
592 | |||
593 | def cleanup_kernels(self): |
|
593 | def cleanup_kernels(self): | |
594 |
""" |
|
594 | """Shutdown all kernels. | |
595 |
|
595 | |||
596 | The kernels will shutdown themselves when this process no longer exists, |
|
596 | The kernels will shutdown themselves when this process no longer exists, | |
597 | but explicit shutdown allows the KernelManagers to cleanup the connection files. |
|
597 | but explicit shutdown allows the KernelManagers to cleanup the connection files. | |
598 | """ |
|
598 | """ | |
599 | self.log.info('Shutting down kernels') |
|
599 | self.log.info('Shutting down kernels') | |
600 |
|
|
600 | self.kernel_manager.shutdown_all() | |
601 | # copy list, since shutdown_kernel deletes keys |
|
|||
602 | for kid in list(km.kernel_ids): |
|
|||
603 | km.shutdown_kernel(kid) |
|
|||
604 |
|
601 | |||
605 | def start(self): |
|
602 | def start(self): | |
606 | ip = self.ip if self.ip else '[all ip addresses on your system]' |
|
603 | ip = self.ip if self.ip else '[all ip addresses on your system]' |
@@ -10,17 +10,21 b' class TestKernelManager(TestCase):' | |||||
10 | km = MultiKernelManager() |
|
10 | km = MultiKernelManager() | |
11 | kid = km.start_kernel() |
|
11 | kid = km.start_kernel() | |
12 | self.assertTrue(kid in km) |
|
12 | self.assertTrue(kid in km) | |
|
13 | self.assertTrue(kid in km.list_kernel_ids()) | |||
13 | self.assertEqual(len(km),1) |
|
14 | self.assertEqual(len(km),1) | |
|
15 | new_kid = km.restart_kernel(kid) | |||
|
16 | self.assertTrue(kid, new_kid) | |||
|
17 | km.interrupt_kernel(kid) | |||
14 | km.kill_kernel(kid) |
|
18 | km.kill_kernel(kid) | |
15 | self.assertTrue(not kid in km) |
|
19 | self.assertTrue(not kid in km) | |
16 |
|
20 | |||
17 | kid = km.start_kernel() |
|
21 | kid = km.start_kernel() | |
18 | self.assertEqual('127.0.0.1',km.get_kernel_ip(kid)) |
|
22 | cdata = km.get_connection_data(kid) | |
19 | port_dict = km.get_kernel_ports(kid) |
|
23 | self.assertEqual('127.0.0.1', cdata['ip']) | |
20 |
self.assertTrue('stdin_port' in |
|
24 | self.assertTrue('stdin_port' in cdata) | |
21 |
self.assertTrue('iopub_port' in |
|
25 | self.assertTrue('iopub_port' in cdata) | |
22 |
self.assertTrue('shell_port' in |
|
26 | self.assertTrue('shell_port' in cdata) | |
23 |
self.assertTrue('hb_port' in |
|
27 | self.assertTrue('hb_port' in cdata) | |
24 | km.get_kernel(kid) |
|
28 | km.get_kernel(kid) | |
25 | km.kill_kernel(kid) |
|
29 | km.kill_kernel(kid) | |
26 |
|
30 |
General Comments 0
You need to be logged in to leave comments.
Login now