Skip to content

Commit 9bc967a

Browse files
committed
shutdown all on pending kernels requires waiting for non-pending state
1 parent de8d2c5 commit 9bc967a

File tree

1 file changed

+29
-5
lines changed

1 file changed

+29
-5
lines changed

jupyter_client/multikernelmanager.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,22 @@ async def _async_start_kernel(self, kernel_name: t.Optional[str] = None, **kwarg
222222

223223
start_kernel = run_sync(_async_start_kernel)
224224

225+
async def _shutdown_kernel_when_ready(
226+
self,
227+
kernel_id: str,
228+
now: t.Optional[bool] = False,
229+
restart: t.Optional[bool] = False,
230+
) -> None:
231+
"""Wait for a pending kernel to be ready
232+
before shutting the kernel down.
233+
"""
234+
# Only do this if using pending kernels
235+
if self._using_pending_kernels():
236+
kernel = self._kernels[kernel_id]
237+
await kernel.ready
238+
# Once out of a pending state, we can call shutdown.
239+
await ensure_async(self.shutdown_kernel(kernel_id, now=now, restart=restart))
240+
225241
async def _async_shutdown_kernel(
226242
self,
227243
kernel_id: str,
@@ -243,9 +259,9 @@ async def _async_shutdown_kernel(
243259
# If we're using pending kernels, block shutdown when a kernel is pending.
244260
if self._using_pending_kernels() and kernel_id in self._pending_kernels:
245261
raise RuntimeError("Kernel is in a pending state. Cannot shutdown.")
246-
# If the kernel isn't in a ready state, wait for it to be ready.
247-
elif kernel_id in self._pending_kernels:
248-
kernel = self._pending_kernels[kernel_id]
262+
# If the kernel is still starting, wait for it to be ready.
263+
elif kernel_id in self._starting_kernels:
264+
kernel = self._starting_kernels[kernel_id]
249265
try:
250266
await kernel
251267
except Exception:
@@ -262,6 +278,9 @@ async def _async_shutdown_kernel(
262278
# Await the kernel if not using pending kernels.
263279
if not self._using_pending_kernels():
264280
await fut
281+
# raise an exception if one occurred during kernel shutdown.
282+
if km.ready.exception():
283+
raise km.ready.exception() # type: ignore
265284

266285
shutdown_kernel = run_sync(_async_shutdown_kernel)
267286

@@ -296,9 +315,14 @@ def remove_kernel(self, kernel_id: str) -> KernelManager:
296315
async def _async_shutdown_all(self, now: bool = False) -> None:
297316
"""Shutdown all kernels."""
298317
kids = self.list_kernel_ids()
299-
kids += list(self._starting_kernels)
300-
futs = [ensure_async(self.shutdown_kernel(kid, now=now)) for kid in set(kids)]
318+
kids += list(self._pending_kernels)
319+
futs = [ensure_async(self._shutdown_kernel_when_ready(kid, now=now)) for kid in set(kids)]
301320
await asyncio.gather(*futs)
321+
# When using "shutdown all", all pending kernels
322+
# should be awaited before exiting this method.
323+
if self._using_pending_kernels():
324+
for km in self._kernels.values():
325+
await km.ready
302326

303327
shutdown_all = run_sync(_async_shutdown_all)
304328

0 commit comments

Comments
 (0)