restarter.py
74 lines
| 2.5 KiB
| text/x-python
|
PythonLexer
Brian E. Granger
|
r10278 | """A basic in process kernel monitor with autorestarting. | ||
This watches a kernel's state using KernelManager.is_alive and auto | ||||
restarts the kernel if it dies. | ||||
""" | ||||
#----------------------------------------------------------------------------- | ||||
# 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 | ||||
#----------------------------------------------------------------------------- | ||||
Brian Granger
|
r10281 | from __future__ import absolute_import | ||
Brian E. Granger
|
r10278 | import zmq | ||
from zmq.eventloop import ioloop | ||||
from IPython.config.configurable import LoggingConfigurable | ||||
from IPython.utils.traitlets import ( | ||||
Instance, Float | ||||
) | ||||
#----------------------------------------------------------------------------- | ||||
# Code | ||||
#----------------------------------------------------------------------------- | ||||
Brian Granger
|
r10282 | class IOLoopKernelRestarter(LoggingConfigurable): | ||
Brian E. Granger
|
r10278 | """Monitor and autorestart a kernel.""" | ||
loop = Instance('zmq.eventloop.ioloop.IOLoop', allow_none=False) | ||||
def _loop_default(self): | ||||
return ioloop.IOLoop.instance() | ||||
MinRK
|
r10284 | kernel_manager = Instance('IPython.kernel.KernelManager') | ||
Brian E. Granger
|
r10278 | |||
time_to_dead = Float(3.0, config=True, | ||||
help="""Kernel heartbeat interval in seconds.""" | ||||
) | ||||
Brian Granger
|
r10280 | _pcallback = None | ||
Brian E. Granger
|
r10278 | def start(self): | ||
Brian Granger
|
r10280 | """Start the polling of the kernel.""" | ||
if self._pcallback is None: | ||||
self._pcallback = ioloop.PeriodicCallback( | ||||
Brian Granger
|
r10282 | self._poll, 1000*self.time_to_dead, self.loop | ||
Brian Granger
|
r10280 | ) | ||
self._pcallback.start() | ||||
def stop(self): | ||||
"""Stop the kernel polling.""" | ||||
if self._pcallback is not None: | ||||
self._pcallback.stop() | ||||
Brian E. Granger
|
r10278 | |||
Brian Granger
|
r10280 | def clear(self): | ||
"""Clear the underlying PeriodicCallback.""" | ||||
self.stop() | ||||
if self._pcallback is not None: | ||||
self._pcallback = None | ||||
def _poll(self): | ||||
Brian Granger
|
r10282 | self.log.info('Polling kernel...') | ||
Brian E. Granger
|
r10278 | if not self.kernel_manager.is_alive(): | ||
# This restart event should leave the connection file in place so | ||||
# the ports are the same. Because this takes place below the | ||||
# MappingKernelManager, the kernel_id will also remain the same. | ||||
Brian Granger
|
r10282 | self.log.info('KernelRestarter: restarting kernel') | ||
Brian E. Granger
|
r10278 | self.kernel_manager.restart_kernel(now=True); | ||