Skip to content

Commit fb23026

Browse files
committed
Fix wait_for_ready() dying early for slow-starting kernels
KernelClient.is_alive() checks heartbeat responsiveness, so it be False early on if the kernel process is slow to start. This can cause `wait_for_ready` to falsely claim the Kernel died before it has finished starting up. The fix is two-fold: 1. Use KernelManager.is_alive when Manager is available (most of the time). This isn't sensitive to slow startup. 2. When Manager isn't available, wait for `is_alive()` to become True at least once before entering the wait for the ready-reply.
1 parent d2ca114 commit fb23026

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

jupyter_client/blocking/client.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ def wait_for_ready(self, timeout=None):
3434
else:
3535
abs_timeout = time.time() + timeout
3636

37+
from ..manager import KernelManager
38+
if not isinstance(self.parent, KernelManager):
39+
# We aren't connected to a manager,
40+
# so first wait for kernel to become responsive to heartbeats
41+
while not self.is_alive():
42+
if time.time() > abs_timeout:
43+
raise RuntimeError("Kernel didn't respond to heartbeats in %d seconds" % timeout)
44+
time.sleep(0.2)
45+
3746
# Wait for kernel info reply on shell channel
3847
while True:
3948
try:

jupyter_client/client.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,13 @@ def hb_channel(self):
181181

182182
def is_alive(self):
183183
"""Is the kernel process still running?"""
184+
from .manager import KernelManager
185+
if isinstance(self.parent, KernelManager):
186+
# We were created by a KernelManager, we can ask them:
187+
return self.parent.is_alive()
184188
if self._hb_channel is not None:
185-
# We didn't start the kernel with this KernelManager so we
186-
# use the heartbeat.
189+
# We don't have access to the KernelManager,
190+
# so we use the heartbeat.
187191
return self._hb_channel.is_beating()
188192
else:
189193
# no heartbeat and not local, we can't tell if it's running,

0 commit comments

Comments
 (0)