Skip to content

Commit 637fb55

Browse files
committed
Merge pull request #141 from minrk/manager-is-alive
Fix wait_for_ready() dying early for slow-starting kernels
2 parents d2ca114 + f06c5c5 commit 637fb55

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

jupyter_client/blocking/client.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ 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+
# This Client was not created by a KernelManager,
40+
# so wait for kernel to become responsive to heartbeats
41+
# before checking for kernel_info reply
42+
while not self.is_alive():
43+
if time.time() > abs_timeout:
44+
raise RuntimeError("Kernel didn't respond to heartbeats in %d seconds and timed out" % timeout)
45+
time.sleep(0.2)
46+
3747
# Wait for kernel info reply on shell channel
3848
while True:
3949
try:

jupyter_client/client.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,14 @@ 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+
# This KernelClient was created by a KernelManager,
187+
# we can ask the parent KernelManager:
188+
return self.parent.is_alive()
184189
if self._hb_channel is not None:
185-
# We didn't start the kernel with this KernelManager so we
186-
# use the heartbeat.
190+
# We don't have access to the KernelManager,
191+
# so we use the heartbeat.
187192
return self._hb_channel.is_beating()
188193
else:
189194
# no heartbeat and not local, we can't tell if it's running,

jupyter_client/tests/signalkernel.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,15 @@ def kernel_info_request(self, *args, **kwargs):
5656
5757
triggers slow-response code in KernelClient.wait_for_ready
5858
"""
59-
time.sleep(1)
6059
return super(SignalTestKernel, self).kernel_info_request(*args, **kwargs)
6160

6261
class SignalTestApp(IPKernelApp):
6362
kernel_class = SignalTestKernel
6463
def init_io(self):
6564
pass # disable stdout/stderr capture
66-
65+
6766
if __name__ == '__main__':
67+
# make startup artificially slow,
68+
# so that we exercise client logic for slow-starting kernels
69+
time.sleep(2)
6870
SignalTestApp.launch_instance()

0 commit comments

Comments
 (0)