##// END OF EJS Templates
Shut down kernels in parallel...
Thomas Kluyver -
Show More
@@ -246,12 +246,45 b' class KernelManager(LoggingConfigurable, ConnectionFileMixin):'
246 self.start_restarter()
246 self.start_restarter()
247 self._connect_control_socket()
247 self._connect_control_socket()
248
248
249 def _send_shutdown_request(self, restart=False):
249 def request_shutdown(self, restart=False):
250 """TODO: send a shutdown request via control channel"""
250 """Send a shutdown request via control channel
251
252 On Windows, this just kills kernels instead, because the shutdown
253 messages don't work.
254 """
255 # FIXME: Shutdown does not work on Windows due to ZMQ errors!
256 if sys.platform == 'win32' and self.has_kernel:
257 return self._kill_kernel()
251 content = dict(restart=restart)
258 content = dict(restart=restart)
252 msg = self.session.msg("shutdown_request", content=content)
259 msg = self.session.msg("shutdown_request", content=content)
253 self.session.send(self._control_socket, msg)
260 self.session.send(self._control_socket, msg)
254
261
262 def wait_shutdown(self, totaltime=1, interval=0.1):
263 """Wait for kernel shutdown, then kill process if it doesn't shutdown.
264
265 This does not send shutdown requests - use :meth:`request_shutdown`
266 first.
267 """
268 for i in range(int(totaltime/interval)):
269 if self.is_alive():
270 time.sleep(interval)
271 else:
272 break
273 else:
274 # OK, we've waited long enough.
275 if self.has_kernel:
276 self._kill_kernel()
277
278 def cleanup(self, restart=False):
279 """Clean up resources when the kernel is shut down"""
280 if not restart:
281 self.cleanup_connection_file()
282 self.cleanup_ipc_files()
283 else:
284 self.cleanup_ipc_files()
285
286 self._close_control_socket()
287
255 def shutdown_kernel(self, now=False, restart=False):
288 def shutdown_kernel(self, now=False, restart=False):
256 """Attempts to the stop the kernel process cleanly.
289 """Attempts to the stop the kernel process cleanly.
257
290
@@ -273,32 +306,16 b' class KernelManager(LoggingConfigurable, ConnectionFileMixin):'
273 # Stop monitoring for restarting while we shutdown.
306 # Stop monitoring for restarting while we shutdown.
274 self.stop_restarter()
307 self.stop_restarter()
275
308
276 # FIXME: Shutdown does not work on Windows due to ZMQ errors!
309 if now:
277 if now or sys.platform == 'win32':
310 self._kill_kernel()
278 if self.has_kernel:
279 self._kill_kernel()
280 else:
311 else:
312 self.request_shutdown(restart=restart)
281 # Don't send any additional kernel kill messages immediately, to give
313 # Don't send any additional kernel kill messages immediately, to give
282 # the kernel a chance to properly execute shutdown actions. Wait for at
314 # the kernel a chance to properly execute shutdown actions. Wait for at
283 # most 1s, checking every 0.1s.
315 # most 1s, checking every 0.1s.
284 self._send_shutdown_request(restart=restart)
316 self.wait_shutdown()
285 for i in range(10):
286 if self.is_alive():
287 time.sleep(0.1)
288 else:
289 break
290 else:
291 # OK, we've waited long enough.
292 if self.has_kernel:
293 self._kill_kernel()
294
317
295 if not restart:
318 self.cleanup(restart=restart)
296 self.cleanup_connection_file()
297 self.cleanup_ipc_files()
298 else:
299 self.cleanup_ipc_files()
300
301 self._close_control_socket()
302
319
303 def restart_kernel(self, now=False, **kw):
320 def restart_kernel(self, now=False, **kw):
304 """Restarts a kernel with the arguments that were used to launch it.
321 """Restarts a kernel with the arguments that were used to launch it.
@@ -131,6 +131,20 b' class MultiKernelManager(LoggingConfigurable):'
131 self.log.info("Kernel shutdown: %s" % kernel_id)
131 self.log.info("Kernel shutdown: %s" % kernel_id)
132 self.remove_kernel(kernel_id)
132 self.remove_kernel(kernel_id)
133
133
134 @kernel_method
135 def request_shutdown(self, kernel_id):
136 """Ask a kernel to shut down by its kernel uuid"""
137
138 @kernel_method
139 def wait_shutdown(self, kernel_id):
140 """Wait for a kernel to finish shutting down, and kill it if it doesn't
141 """
142 self.log.info("Kernel shutdown: %s" % kernel_id)
143
144 @kernel_method
145 def cleanup(self, kernel_id):
146 """Clean up a kernel's resources"""
147
134 def remove_kernel(self, kernel_id):
148 def remove_kernel(self, kernel_id):
135 """remove a kernel from our mapping.
149 """remove a kernel from our mapping.
136
150
@@ -143,8 +157,12 b' class MultiKernelManager(LoggingConfigurable):'
143
157
144 def shutdown_all(self, now=False):
158 def shutdown_all(self, now=False):
145 """Shutdown all kernels."""
159 """Shutdown all kernels."""
146 for kid in self.list_kernel_ids():
160 kids = self.list_kernel_ids()
147 self.shutdown_kernel(kid, now=now)
161 for kid in kids:
162 self.request_shutdown(kid)
163 for kid in kids:
164 self.wait_shutdown(kid)
165 self.cleanup(kid)
148
166
149 @kernel_method
167 @kernel_method
150 def interrupt_kernel(self, kernel_id):
168 def interrupt_kernel(self, kernel_id):
General Comments 0
You need to be logged in to leave comments. Login now