##// END OF EJS Templates
Show terminals as terminals/name...
Show terminals as terminals/name Bigger click target

File last commit:

r17713:ea83bb5c
r18559:91d5e5f6
Show More
restarter.py
111 lines | 3.5 KiB | text/x-python | PythonLexer
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295 """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.
"""
MinRK
add secondary `debug` flag for heartbeats...
r17713 # Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295
from IPython.config.configurable import LoggingConfigurable
from IPython.utils.traitlets import (
MinRK
change how failed restarts are detected...
r10334 Instance, Float, Dict, Bool, Integer,
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295 )
class KernelRestarter(LoggingConfigurable):
"""Monitor and autorestart a kernel."""
kernel_manager = Instance('IPython.kernel.KernelManager')
MinRK
add secondary `debug` flag for heartbeats...
r17713
debug = Bool(False, config=True,
help="""Whether to include every poll event in debugging output.
Has to be set explicitly, because there will be *a lot* of output.
"""
)
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295 time_to_dead = Float(3.0, config=True,
help="""Kernel heartbeat interval in seconds."""
)
MinRK
fire 'dead' callbacks when kernel dies before its first heartbeat
r10314
MinRK
change how failed restarts are detected...
r10334 restart_limit = Integer(5, config=True,
help="""The number of consecutive autorestarts before the kernel is presumed dead."""
)
MinRK
fix inverted default value for KR._restarting
r10318 _restarting = Bool(False)
MinRK
change how failed restarts are detected...
r10334 _restart_count = Integer(0)
MinRK
fire 'dead' callbacks when kernel dies before its first heartbeat
r10314
MinRK
expose restart callbacks via KernelManager
r10313 callbacks = Dict()
def _callbacks_default(self):
return dict(restart=[], dead=[])
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295
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")
MinRK
expose restart callbacks via KernelManager
r10313 def add_callback(self, f, event='restart'):
"""register a callback to fire on a particular event
Possible values for event:
'restart' (default): kernel has died, and will be restarted.
'dead': restart has failed, kernel will be left dead.
"""
self.callbacks[event].append(f)
def remove_callback(self, f, event='restart'):
"""unregister a callback to fire on a particular event
Possible values for event:
'restart' (default): kernel has died, and will be restarted.
'dead': restart has failed, kernel will be left dead.
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295
MinRK
expose restart callbacks via KernelManager
r10313 """
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295 try:
MinRK
expose restart callbacks via KernelManager
r10313 self.callbacks[event].remove(f)
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295 except ValueError:
pass
MinRK
fire 'dead' callbacks when kernel dies before its first heartbeat
r10314 def _fire_callbacks(self, event):
"""fire our callbacks for a particular event"""
for callback in self.callbacks[event]:
try:
callback()
except Exception as e:
self.log.error("KernelRestarter: %s callback %r failed", event, callback, exc_info=True)
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295 def poll(self):
MinRK
add secondary `debug` flag for heartbeats...
r17713 if self.debug:
self.log.debug('Polling kernel...')
MinRK
cleanup boundaries of MultiKernelManager and KernelRestarter classes...
r10295 if not self.kernel_manager.is_alive():
MinRK
fire 'dead' callbacks when kernel dies before its first heartbeat
r10314 if self._restarting:
MinRK
change how failed restarts are detected...
r10334 self._restart_count += 1
else:
self._restart_count = 1
if self._restart_count >= self.restart_limit:
MinRK
fire 'dead' callbacks when kernel dies before its first heartbeat
r10314 self.log.warn("KernelRestarter: restart failed")
self._fire_callbacks('dead')
self._restarting = False
MinRK
change how failed restarts are detected...
r10334 self._restart_count = 0
MinRK
cleanup restart logic...
r10320 self.stop()
MinRK
fire 'dead' callbacks when kernel dies before its first heartbeat
r10314 else:
MinRK
change how failed restarts are detected...
r10334 self.log.info('KernelRestarter: restarting kernel (%i/%i)',
self._restart_count,
self.restart_limit
)
MinRK
fire 'dead' callbacks when kernel dies before its first heartbeat
r10314 self._fire_callbacks('restart')
self.kernel_manager.restart_kernel(now=True)
self._restarting = True
MinRK
cleanup restart logic...
r10320 else:
if self._restarting:
self.log.debug("KernelRestarter: restart apparently succeeded")
self._restarting = False