"""A basic kernel monitor with autorestarting. This watches a kernel's state using KernelManager.is_alive and auto restarts the kernel if it dies. It is an incomplete base class, and must be subclassed. """ #----------------------------------------------------------------------------- # Copyright (C) 2013 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from IPython.config.configurable import LoggingConfigurable from IPython.utils.traitlets import ( Instance, Float, List, ) #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class KernelRestarter(LoggingConfigurable): """Monitor and autorestart a kernel.""" kernel_manager = Instance('IPython.kernel.KernelManager') time_to_dead = Float(3.0, config=True, help="""Kernel heartbeat interval in seconds.""" ) _callbacks = List() def start(self): """Start the polling of the kernel.""" raise NotImplementedError("Must be implemented in a subclass") def stop(self): """Stop the kernel polling.""" raise NotImplementedError("Must be implemented in a subclass") def register_callback(self, f): """register a callback to fire""" self._callbacks.append(f) def unregister_callback(self, f): try: self._callbacks.remove(f) except ValueError: pass def poll(self): self.log.debug('Polling kernel...') if not self.kernel_manager.is_alive(): self.log.info('KernelRestarter: restarting kernel') for callback in self._callbacks: try: callback() except Exception as e: self.log.error("Kernel restart callback %r failed", callback, exc_info=True) self.kernel_manager.restart_kernel(now=True)