On Wed, Nov 8, 2017 at 8:59 AM, Edward K. Ream <[email protected]> wrote:
>
The next step will
be to override methods so that checking for results happens asynchronously.
Abbreviate NonBlockingClient as nbc and NonBlockingKernelClient as nbkc.
I defined nbc.get_msg to be the same as the BlockingClient.get_msg and
nbkc.wait_for_ready to be the same as the
BlockingKernelClient.wait_for_ready.
To make this work, we must the NonBlockingKernelClient class this way:
class NonBlockingKernelClient (jupyter_client.blocking.client.
BlockingKernelClient):
shell_channel_class = NonBlockingChannel
iopub_channel_class = NonBlockingChannel
stdin_channel_class = NonBlockingChannel
# hb_channel_class = Type(jupyter_client.channels.HBChannel)
# no change needed.
@others
Now nbc.get_msg and nbkc.wait_for_ready are called as expected.
This is a big step forward. It appears that only these two methods would
have to change to make the classes non-blocking.
Here is nbc.get_msg:
def get_msg(self, block=True, timeout=None):
""" Gets a message if there is one that is ready. """
# g.trace('(NonBlockingChannel)', 'block', block, 'timeout',
repr(timeout))
if block:
if timeout is not None:
timeout *= 1000 # seconds to ms
ready = self.socket.poll(timeout)
else:
ready = self.socket.poll(timeout=0)
ready = self.socket.poll(timeout=0)
if ready:
return self._recv()
else:
raise Empty
And here is nbkc.wait_for_ready:
def wait_for_ready(self, timeout=None):
"""Waits for a response when a client is blocked
- Sets future time for timeout
- Blocks on shell channel until a message is received
- Exit if the kernel has died
- If client times out before receiving a message from the kernel, send
RuntimeError
- Flush the IOPub channel
"""
g.trace('timeout', repr(timeout), 'shell_channel', self.shell_channel)
abs_timeout = float('inf') if timeout is None else time.time() + timeout
#
# from ..manager import KernelManager
# if not isinstance(self.parent,
jupyter_client.manager.KernelManager):
# [snip]
# Wait for kernel info reply on shell channel
while True:
try:
msg = self.shell_channel.get_msg(block=True, timeout=1)
except Empty:
pass
else:
if msg['msg_type'] == 'kernel_info_reply':
self._handle_kernel_info_reply(msg)
break
if not self.is_alive():
raise RuntimeError('Kernel died before replying to kernel_info')
# Check if current time is ready check time plus timeout
if time.time() > abs_timeout:
raise RuntimeError("Kernel didn't respond in %d seconds" %
timeout)
# Flush IOPub channel
while True:
try:
msg = self.iopub_channel.get_msg(block=True, timeout=0.2)
except Empty:
break
Unless I am mistaken, only these two methods will have to change.
Finally, main() now computes successive values of sine(x):
def main(code):
km, kc = start_non_blocking_kernel()
kc.execute(code=code, user_expressions={'a':'a'})
msg = kc.get_shell_msg()
result = getIn(msg, ['content', 'user_expressions', 'a', 'data',
'text/plain'])
g.trace('sin(%2s)=%s' % (g.app.permanentScriptDict.get('val'), result))
Example output:
wait_for_ready timeout 60 shell_channel <__main__.NonBlockingChannel object
at 0x0B5C9610>
main sin( 1)=0.0
main sin( 2)=0.8414709848078965
main sin( 3)=0.9092974268256817
*Summary*
Probably only nbc.get_msg and nbkc.wait_for_ready need to be changed. Any
help with this would be appreciated.
Edward
--
You received this message because you are subscribed to the Google Groups
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.