Skip to content

Commit d2c974a

Browse files
authored
Introduce ServerKernelManager class (#1101)
1 parent 222e713 commit d2c974a

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

jupyter_server/services/kernels/kernelmanager.py

+28-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
# Distributed under the terms of the Modified BSD License.
88
import asyncio
99
import os
10+
import warnings
1011
from collections import defaultdict
1112
from datetime import datetime, timedelta
1213
from functools import partial
1314

15+
from jupyter_client.ioloop.manager import AsyncIOLoopKernelManager
1416
from jupyter_client.multikernelmanager import (
1517
AsyncMultiKernelManager,
1618
MultiKernelManager,
@@ -36,7 +38,7 @@
3638

3739
from jupyter_server._tz import isoformat, utcnow
3840
from jupyter_server.prometheus.metrics import KERNEL_CURRENTLY_RUNNING_TOTAL
39-
from jupyter_server.utils import ensure_async, to_os_path
41+
from jupyter_server.utils import ensure_async, import_item, to_os_path
4042

4143

4244
class MappingKernelManager(MultiKernelManager):
@@ -656,10 +658,34 @@ async def cull_kernel_if_idle(self, kernel_id):
656658
class AsyncMappingKernelManager(MappingKernelManager, AsyncMultiKernelManager):
657659
@default("kernel_manager_class")
658660
def _default_kernel_manager_class(self):
659-
return "jupyter_client.ioloop.AsyncIOLoopKernelManager"
661+
return "jupyter_server.services.kernels.kernelmanager.ServerKernelManager"
662+
663+
@validate("kernel_manager_class")
664+
def _validate_kernel_manager_class(self, proposal):
665+
km_class_value = proposal.value
666+
km_class = import_item(km_class_value)
667+
if not issubclass(km_class, ServerKernelManager):
668+
warnings.warn(
669+
f"KernelManager class '{km_class}' is not a subclass of 'ServerKernelManager'. Custom "
670+
"KernelManager classes should derive from 'ServerKernelManager' beginning with jupyter-server 2.0 "
671+
"or risk missing functionality. Continuing...",
672+
FutureWarning,
673+
stacklevel=3,
674+
)
675+
return km_class_value
660676

661677
def __init__(self, **kwargs):
662678
self.pinned_superclass = MultiKernelManager
663679
self._pending_kernel_tasks = {}
664680
self.pinned_superclass.__init__(self, **kwargs)
665681
self.last_kernel_activity = utcnow()
682+
683+
684+
class ServerKernelManager(AsyncIOLoopKernelManager):
685+
686+
# Define activity-related attributes:
687+
execution_state = Unicode(
688+
None, allow_none=True, help="The current execution state of the kernel"
689+
)
690+
reason = Unicode("", help="The reason for the last failure against the kernel")
691+
last_activity = Instance(datetime, help="The last activity on the kernel")

tests/services/kernels/test_config.py

+8
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,11 @@ def test_async_kernel_manager(jp_configurable_serverapp):
2121
]
2222
app = jp_configurable_serverapp(argv=argv)
2323
assert isinstance(app.kernel_manager, AsyncMappingKernelManager)
24+
25+
26+
def test_not_server_kernel_manager(jp_configurable_serverapp):
27+
argv = [
28+
"--AsyncMappingKernelManager.kernel_manager_class=jupyter_client.ioloop.manager.AsyncIOLoopKernelManager"
29+
]
30+
with pytest.warns(FutureWarning, match="is not a subclass of 'ServerKernelManager'"):
31+
jp_configurable_serverapp(argv=argv)

0 commit comments

Comments
 (0)