​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.

Reply via email to