##// END OF EJS Templates
start to migrate to variables
start to migrate to variables

File last commit:

r9157:6f4e7b97
r9260:95a4d0ad
Show More
kernelmanager.py
364 lines | 12.4 KiB | text/x-python | PythonLexer
Brian E. Granger
More review changes....
r4609 """A kernel manager for multiple kernels.
Authors:
* Brian Granger
"""
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343
Brian E. Granger
Refactoring the notebook app to support the new config system.
r4344 #-----------------------------------------------------------------------------
Brian E. Granger
More review changes....
r4609 # Copyright (C) 2008-2011 The IPython Development Team
Brian E. Granger
Updating the notebook to work with the latex master....
r4348 #
# Distributed under the terms of the BSD License. The full license is in
Brian E. Granger
More review changes....
r4609 # the file COPYING, distributed as part of this software.
Brian E. Granger
Updating the notebook to work with the latex master....
r4348 #-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
Brian E. Granger
Refactoring the notebook app to support the new config system.
r4344 # Imports
#-----------------------------------------------------------------------------
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 import os
Brian Granger
Different clients now share a single zmq session....
r4306 import uuid
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 import zmq
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 from zmq.eventloop.zmqstream import ZMQStream
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343
Brian E. Granger
Adding kernel/notebook associations.
r4494 from tornado import web
Brian E. Granger
Notebook app debugging....
r4345 from IPython.config.configurable import LoggingConfigurable
MinRK
make MultiKernelManager.kernel_manager_class configurable...
r6317 from IPython.utils.importstring import import_item
from IPython.utils.traitlets import (
Instance, Dict, List, Unicode, Float, Integer, Any, DottedObjectName,
)
Brian E. Granger
Refactoring the notebook app to support the new config system.
r4344 #-----------------------------------------------------------------------------
# Classes
#-----------------------------------------------------------------------------
Brian Granger
Work on the server side of the html notebook.
r4297
Brian Granger
Basic server for htmlnotebook working.
r4298 class DuplicateKernelError(Exception):
pass
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 class MultiKernelManager(LoggingConfigurable):
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 """A class for managing multiple kernels."""
MinRK
make MultiKernelManager.kernel_manager_class configurable...
r6317
kernel_manager_class = DottedObjectName(
MinRK
enable graceful restart of kernels in notebook
r7626 "IPython.zmq.blockingkernelmanager.BlockingKernelManager", config=True,
MinRK
make MultiKernelManager.kernel_manager_class configurable...
r6317 help="""The kernel manager class. This is configurable to allow
subclassing of the KernelManager for customized behavior.
"""
)
def _kernel_manager_class_changed(self, name, old, new):
self.kernel_manager_factory = import_item(new)
kernel_manager_factory = Any(help="this is kernel_manager_class after import")
def _kernel_manager_factory_default(self):
return import_item(self.kernel_manager_class)
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 context = Instance('zmq.Context')
def _context_default(self):
return zmq.Context.instance()
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960
connection_dir = Unicode('')
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 _kernels = Dict()
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 def list_kernel_ids(self):
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 """Return a list of the kernel ids of the active kernels."""
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 # Create a copy so we can iterate over kernels in operations
# that delete keys.
return list(self._kernels.keys())
Brian Granger
Work on the server side of the html notebook.
r4297
def __len__(self):
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 """Return the number of running kernels."""
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 return len(self.list_kernel_ids())
Brian Granger
Work on the server side of the html notebook.
r4297
def __contains__(self, kernel_id):
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 return kernel_id in self._kernels
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 def start_kernel(self, **kwargs):
Brian E. Granger
Allow caller of MultiKernelManager.start_kernel to pass kernel_id.
r9111 """Start a new kernel.
The caller can pick a kernel_id by passing one in as a keyword arg,
otherwise one will be picked using a uuid.
Brian E. Granger
Fixing last few things with the test suite for kernel managers.
r9132
To silence the kernel's stdout/stderr, call this using::
km.start_kernel(stdout=PIPE, stderr=PIPE)
Brian E. Granger
Allow caller of MultiKernelManager.start_kernel to pass kernel_id.
r9111 """
kernel_id = kwargs.pop('kernel_id', unicode(uuid.uuid4()))
if kernel_id in self:
raise DuplicateKernelError('Kernel already exists: %s' % kernel_id)
Brian E. Granger
Adding tested ipc support to MultiKernelManager.
r9116 # kernel_manager_factory is the constructor for the KernelManager
# subclass we are using. It can be configured as any Configurable,
# including things like its transport and ip.
MinRK
make MultiKernelManager.kernel_manager_class configurable...
r6317 km = self.kernel_manager_factory(connection_file=os.path.join(
MinRK
enable HMAC message signing by default in notebook kernels...
r4963 self.connection_dir, "kernel-%s.json" % kernel_id),
config=self.config,
Brian Granger
Work on the server side of the html notebook.
r4297 )
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 km.start_kernel(**kwargs)
MinRK
use shutdown_kernel instead of hard kill in notebook
r7627 # start just the shell channel, needed for graceful restart
Brian Granger
Creating an ABC for kernel managers and channels.
r9121 km.start_channels(shell=True, iopub=False, stdin=False, hb=False)
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 self._kernels[kernel_id] = km
Brian Granger
Basic server for htmlnotebook working.
r4298 return kernel_id
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 def shutdown_kernel(self, kernel_id, now=False):
MinRK
use shutdown_kernel instead of hard kill in notebook
r7627 """Shutdown a kernel by its kernel uuid.
Parameters
==========
kernel_id : uuid
The id of the kernel to shutdown.
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 now : bool
Should the kernel be shutdown forcibly using a signal.
MinRK
use shutdown_kernel instead of hard kill in notebook
r7627 """
Brian E. Granger
Adding calls to shell_channel.stop() to shutdown....
r9118 k = self.get_kernel(kernel_id)
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 k.shutdown_kernel(now=now)
Brian E. Granger
Adding calls to shell_channel.stop() to shutdown....
r9118 k.shell_channel.stop()
MinRK
use shutdown_kernel instead of hard kill in notebook
r7627 del self._kernels[kernel_id]
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 def shutdown_all(self, now=False):
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 """Shutdown all kernels."""
for kid in self.list_kernel_ids():
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 self.shutdown_kernel(kid, now=now)
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112
Brian Granger
Work on the server side of the html notebook.
r4297 def interrupt_kernel(self, kernel_id):
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 """Interrupt (SIGINT) the kernel by its uuid.
Parameters
==========
kernel_id : uuid
The id of the kernel to interrupt.
"""
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 return self.get_kernel(kernel_id).interrupt_kernel()
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545
Brian Granger
Work on the server side of the html notebook.
r4297 def signal_kernel(self, kernel_id, signum):
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 """Sends a signal to the kernel by its uuid.
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343
Note that since only SIGTERM is supported on Windows, this function
is only useful on Unix systems.
Parameters
==========
kernel_id : uuid
The id of the kernel to signal.
Brian Granger
Work on the server side of the html notebook.
r4297 """
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 return self.get_kernel(kernel_id).signal_kernel(signum)
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
Removing unused code in the notebook MappingKernelManager....
r9033 def restart_kernel(self, kernel_id):
"""Restart a kernel by its uuid, keeping the same ports.
Parameters
==========
kernel_id : uuid
The id of the kernel to interrupt.
"""
return self.get_kernel(kernel_id).restart_kernel()
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 def get_kernel(self, kernel_id):
"""Get the single KernelManager object for a kernel by its uuid.
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343
Parameters
==========
kernel_id : uuid
The id of the kernel.
"""
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 km = self._kernels.get(kernel_id)
if km is not None:
return km
Brian Granger
Work on the server side of the html notebook.
r4297 else:
raise KeyError("Kernel with id not found: %s" % kernel_id)
Brian E. Granger
Adding tested ipc support to MultiKernelManager.
r9116 def get_connection_info(self, kernel_id):
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 """Return a dictionary of connection data for a kernel.
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343
Parameters
==========
kernel_id : uuid
The id of the kernel.
Returns
=======
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 connection_dict : dict
A dict of the information needed to connect to a kernel.
This includes the ip address and the integer port
numbers of the different channels (stdin_port, iopub_port,
shell_port, hb_port).
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 """
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 km = self.get_kernel(kernel_id)
Brian E. Granger
Adding tested ipc support to MultiKernelManager.
r9116 return dict(transport=km.transport,
ip=km.ip,
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 shell_port=km.shell_port,
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 iopub_port=km.iopub_port,
stdin_port=km.stdin_port,
hb_port=km.hb_port,
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 )
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
Adding tested ipc support to MultiKernelManager.
r9116 def _make_url(self, transport, ip, port):
"""Make a ZeroMQ URL for a given transport, ip and port."""
if transport == 'tcp':
return "tcp://%s:%i" % (ip, port)
else:
return "%s://%s-%s" % (transport, ip, port)
MinRK
fix KeyError creating ZMQStreams in notebook...
r9157 def _create_connected_stream(self, kernel_id, socket_type, channel):
Brian E. Granger
Adding tested ipc support to MultiKernelManager.
r9116 """Create a connected ZMQStream for a kernel."""
cinfo = self.get_connection_info(kernel_id)
MinRK
fix KeyError creating ZMQStreams in notebook...
r9157 url = self._make_url(cinfo['transport'], cinfo['ip'],
cinfo['%s_port' % channel]
)
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 sock = self.context.socket(socket_type)
Brian E. Granger
Adding tested ipc support to MultiKernelManager.
r9116 self.log.info("Connecting to: %s" % url)
sock.connect(url)
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 return ZMQStream(sock)
def create_iopub_stream(self, kernel_id):
"""Return a ZMQStream object connected to the iopub channel.
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343
Parameters
==========
kernel_id : uuid
The id of the kernel.
Returns
=======
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 stream : ZMQStream
Brian E. Granger
Refactored htmlnotebook session and kernel manager....
r4343 """
MinRK
fix KeyError creating ZMQStreams in notebook...
r9157 iopub_stream = self._create_connected_stream(kernel_id, zmq.SUB, 'iopub')
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 iopub_stream.socket.setsockopt(zmq.SUBSCRIBE, b'')
return iopub_stream
Brian Granger
Work on the server side of the html notebook.
r4297
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 def create_shell_stream(self, kernel_id):
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 """Return a ZMQStream object connected to the shell channel.
Parameters
==========
kernel_id : uuid
The id of the kernel.
Returns
=======
stream : ZMQStream
"""
MinRK
fix KeyError creating ZMQStreams in notebook...
r9157 shell_stream = self._create_connected_stream(kernel_id, zmq.DEALER, 'shell')
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 return shell_stream
Brian E. Granger
Adding kernel/notebook associations.
r4494
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 def create_hb_stream(self, kernel_id):
Brian E. Granger
General cleanup of kernelmanger.MultiKernelManager.
r9112 """Return a ZMQStream object connected to the hb channel.
Parameters
==========
kernel_id : uuid
The id of the kernel.
Returns
=======
stream : ZMQStream
"""
MinRK
fix KeyError creating ZMQStreams in notebook...
r9157 hb_stream = self._create_connected_stream(kernel_id, zmq.REQ, 'hb')
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 return hb_stream
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 class MappingKernelManager(MultiKernelManager):
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 """A KernelManager that handles notebok mapping and HTTP error handling"""
Brian E. Granger
Adding kernel/notebook associations.
r4494
kernel_argv = List(Unicode)
MinRK
add first_beat delay to notebook heartbeats...
r5812
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 time_to_dead = Float(3.0, config=True, help="""Kernel heartbeat interval in seconds.""")
MinRK
add first_beat delay to notebook heartbeats...
r5812 first_beat = Float(5.0, config=True, help="Delay (in seconds) before sending first heartbeat.")
MinRK
add Integer traitlet...
r5344 max_msg_size = Integer(65536, config=True, help="""
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 The max raw message size accepted from the browser
over a WebSocket connection.
""")
Brian E. Granger
Adding kernel/notebook associations.
r4494
_notebook_mapping = Dict()
#-------------------------------------------------------------------------
# Methods for managing kernels and sessions
#-------------------------------------------------------------------------
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495 def kernel_for_notebook(self, notebook_id):
"""Return the kernel_id for a notebook_id or None."""
return self._notebook_mapping.get(notebook_id)
def set_kernel_for_notebook(self, notebook_id, kernel_id):
"""Associate a notebook with a kernel."""
if notebook_id is not None:
self._notebook_mapping[notebook_id] = kernel_id
Brian E. Granger
Adding kernel/notebook associations.
r4494 def notebook_for_kernel(self, kernel_id):
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495 """Return the notebook_id for a kernel_id or None."""
Brian E. Granger
Adding kernel/notebook associations.
r4494 notebook_ids = [k for k, v in self._notebook_mapping.iteritems() if v == kernel_id]
if len(notebook_ids) == 1:
return notebook_ids[0]
else:
return None
def delete_mapping_for_kernel(self, kernel_id):
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495 """Remove the kernel/notebook mapping for kernel_id."""
Brian E. Granger
Adding kernel/notebook associations.
r4494 notebook_id = self.notebook_for_kernel(kernel_id)
if notebook_id is not None:
del self._notebook_mapping[notebook_id]
MinRK
use notebook-dir as cwd for kernels
r7558 def start_kernel(self, notebook_id=None, **kwargs):
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 """Start a kernel for a notebok an return its kernel_id.
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495
Parameters
----------
notebook_id : uuid
The uuid of the notebook to associate the new kernel with. If this
is not None, this kernel will be persistent whenever the notebook
requests a kernel.
"""
kernel_id = self.kernel_for_notebook(notebook_id)
Brian E. Granger
Adding kernel/notebook associations.
r4494 if kernel_id is None:
kwargs['extra_arguments'] = self.kernel_argv
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 kernel_id = super(MappingKernelManager, self).start_kernel(**kwargs)
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495 self.set_kernel_for_notebook(notebook_id, kernel_id)
self.log.info("Kernel started: %s" % kernel_id)
Brian E. Granger
Adding kernel/notebook associations.
r4494 self.log.debug("Kernel args: %r" % kwargs)
else:
self.log.info("Using existing kernel: %s" % kernel_id)
return kernel_id
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 def shutdown_kernel(self, kernel_id, now=False):
MinRK
use shutdown_kernel instead of hard kill in notebook
r7627 """Shutdown a kernel and remove its notebook association."""
self._check_kernel_id(kernel_id)
Brian E. Granger
Make KernelManager.kill_kernel private....
r9130 super(MappingKernelManager, self).shutdown_kernel(
kernel_id, now=now
)
MinRK
use shutdown_kernel instead of hard kill in notebook
r7627 self.delete_mapping_for_kernel(kernel_id)
self.log.info("Kernel shutdown: %s" % kernel_id)
Brian E. Granger
Adding kernel/notebook associations.
r4494 def interrupt_kernel(self, kernel_id):
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495 """Interrupt a kernel."""
Brian E. Granger
Adding messages to HTTPError raising....
r4676 self._check_kernel_id(kernel_id)
Brian E. Granger
Major refactor of kernel connection management in the notebook....
r4545 super(MappingKernelManager, self).interrupt_kernel(kernel_id)
self.log.info("Kernel interrupted: %s" % kernel_id)
Brian E. Granger
Adding kernel/notebook associations.
r4494
def restart_kernel(self, kernel_id):
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495 """Restart a kernel while keeping clients connected."""
Brian E. Granger
Adding messages to HTTPError raising....
r4676 self._check_kernel_id(kernel_id)
Brian E. Granger
Removing unused code in the notebook MappingKernelManager....
r9033 super(MappingKernelManager, self).restart_kernel(kernel_id)
MinRK
use zmq.KernelManager to manage individual kernels in notebook...
r4960 self.log.info("Kernel restarted: %s" % kernel_id)
Brian E. Granger
Adding kernel/notebook associations.
r4494
Brian E. Granger
WebSocket url is now passed to browser when a kernel is started.
r4572 def create_iopub_stream(self, kernel_id):
Brian E. Granger
Adding messages to HTTPError raising....
r4676 """Create a new iopub stream."""
self._check_kernel_id(kernel_id)
Brian E. Granger
WebSocket url is now passed to browser when a kernel is started.
r4572 return super(MappingKernelManager, self).create_iopub_stream(kernel_id)
def create_shell_stream(self, kernel_id):
Brian E. Granger
Adding messages to HTTPError raising....
r4676 """Create a new shell stream."""
self._check_kernel_id(kernel_id)
Brian E. Granger
WebSocket url is now passed to browser when a kernel is started.
r4572 return super(MappingKernelManager, self).create_shell_stream(kernel_id)
def create_hb_stream(self, kernel_id):
Brian E. Granger
Adding messages to HTTPError raising....
r4676 """Create a new hb stream."""
self._check_kernel_id(kernel_id)
Brian E. Granger
WebSocket url is now passed to browser when a kernel is started.
r4572 return super(MappingKernelManager, self).create_hb_stream(kernel_id)
Brian E. Granger
Fixed subtle bug in kernel restarting....
r4495
Brian E. Granger
Adding messages to HTTPError raising....
r4676 def _check_kernel_id(self, kernel_id):
"""Check a that a kernel_id exists and raise 404 if not."""
if kernel_id not in self:
raise web.HTTPError(404, u'Kernel does not exist: %s' % kernel_id)