Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for async kernel management #4479

Merged
merged 10 commits into from
Apr 4, 2020
34 changes: 28 additions & 6 deletions notebook/notebookapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from __future__ import absolute_import, print_function

import notebook
import asyncio
import binascii
import datetime
import errno
Expand Down Expand Up @@ -75,7 +76,7 @@

from .base.handlers import Template404, RedirectWithParams
from .log import log_request
from .services.kernels.kernelmanager import MappingKernelManager
from .services.kernels.kernelmanager import MappingKernelManager, AsyncMappingKernelManager
from .services.config import ConfigManager
from .services.contents.manager import ContentsManager
from .services.contents.filemanager import FileContentsManager
Expand Down Expand Up @@ -106,7 +107,14 @@
from notebook._sysinfo import get_sys_info

from ._tz import utcnow, utcfromtimestamp
from .utils import url_path_join, check_pid, url_escape, urljoin, pathname2url
from .utils import url_path_join, check_pid, url_escape, urljoin, pathname2url, run_sync

# Check if we can use async kernel management
try:
from jupyter_client import AsyncMultiKernelManager
async_kernel_mgmt_available = True
except ImportError:
async_kernel_mgmt_available = False

#-----------------------------------------------------------------------------
# Module globals
Expand Down Expand Up @@ -1177,6 +1185,7 @@ def _update_mathjax_config(self, change):

kernel_manager_class = Type(
default_value=MappingKernelManager,
klass=MappingKernelManager,
config=True,
help=_('The kernel manager class to use.')
)
Expand Down Expand Up @@ -1374,12 +1383,24 @@ def init_configurables(self):
self.kernel_spec_manager = self.kernel_spec_manager_class(
parent=self,
)

self.kernel_manager = self.kernel_manager_class(
parent=self,
log=self.log,
connection_dir=self.runtime_dir,
kernel_spec_manager=self.kernel_spec_manager,
)
# Ensure the appropriate version of Python and jupyter_client is available.
if isinstance(self.kernel_manager, AsyncMappingKernelManager):
if sys.version_info < (3, 6): # Can be removed once 3.5 is dropped.
raise ValueError("You are using `AsyncMappingKernelManager` in Python 3.5 (or lower) "
"which is not supported. Please upgrade Python to 3.6+ or change kernel managers.")
if not async_kernel_mgmt_available: # Can be removed once jupyter_client >= 6.1 is required.
raise ValueError("You are using `AsyncMappingKernelManager` without an appropriate "
"jupyter_client installed! Please upgrade jupyter_client or change kernel managers.")
self.log.info("Asynchronous kernel management has been configured to use '{}'.".
format(self.kernel_manager.__class__.__name__))

self.contents_manager = self.contents_manager_class(
parent=self,
log=self.log,
Expand Down Expand Up @@ -1782,7 +1803,7 @@ def cleanup_kernels(self):
n_kernels = len(self.kernel_manager.list_kernel_ids())
kernel_msg = trans.ngettext('Shutting down %d kernel', 'Shutting down %d kernels', n_kernels)
self.log.info(kernel_msg % n_kernels)
self.kernel_manager.shutdown_all()
run_sync(self.kernel_manager.shutdown_all())

def notebook_info(self, kernel_count=True):
"Return the current working directory and the server url information"
Expand All @@ -1793,7 +1814,8 @@ def notebook_info(self, kernel_count=True):
info += kernel_msg % n_kernels
info += "\n"
# Format the info so that the URL fits on a single line in 80 char display
info += _("The Jupyter Notebook is running at:\n%s") % self.display_url
info += _("Jupyter Notebook {version} is running at:\n{url}".
format(version=NotebookApp.version, url=self.display_url))
if self.gateway_config.gateway_enabled:
info += _("\nKernels will be managed by the Gateway server running at:\n%s") % self.gateway_config.url
return info
Expand Down Expand Up @@ -1897,8 +1919,8 @@ def launch_browser(self):
assembled_url = urljoin('file:', pathname2url(open_file))
else:
assembled_url = url_path_join(self.connection_url, uri)
b = lambda: browser.open(assembled_url, new=self.webbrowser_open_new)

b = lambda: browser.open(assembled_url, new=self.webbrowser_open_new)
threading.Thread(target=b).start()

def start(self):
Expand Down
2 changes: 1 addition & 1 deletion notebook/services/kernels/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class KernelActionHandler(APIHandler):
def post(self, kernel_id, action):
km = self.kernel_manager
if action == 'interrupt':
km.interrupt_kernel(kernel_id)
yield maybe_future(km.interrupt_kernel(kernel_id))
self.set_status(204)
if action == 'restart':

Expand Down
Loading