Skip to content

Confusing problems with shutdown_reply being received on iopub #170

@gibiansky

Description

@gibiansky

Note #1: The IPython kernel sends a status: "ok" key with the shutdown_reply, which is not documented in the messaging spec. Extra keys are generally not a problem but could also be documented if they play any role (or it can also be documented that extra keys should never be rejected).

More serious issue:

I am getting the shutdown_reply sent on the iopub channel, which can break client libraries. This seems to be somewhat tricky to reproduce, which has me confused.

Here is how you I can reproduce it:

Start a kernel:

python -m ipykernel

Find the absolute path to kernel-DDDDD.json in the stdout of that process.

Then, run jupyter console, and enter the following code (substituting in kernel-DDDDD.json as appropriate):

from pprint import pprint
from jupyter_client.consoleapp import JupyterConsoleApp
import time

class MyKernelApp(JupyterConsoleApp):
    def __init__(self, connection_file, runtime_dir):
        self._dispatching = False
        self.existing = connection_file
        self.runtime_dir = runtime_dir
        self.initialize()

app = MyKernelApp("/Users/silver/Library/Jupyter/runtime/kernel-23605.json", "/tmp")
kc = app.kernel_client
# Clear status messages
time.sleep(0.5)
kc.iopub_channel.get_msgs()

kc.shutdown()
time.sleep(0.5)
[m["header"]["msg_type"] for m in kc.iopub_channel.get_msgs()]

This will result in a list of message types which include shutdown_reply, which does not make sense, because this is the iopub channel.

Similarly, the following code reproduces the problem for me:

multimanager = MultiKernelManager()
manager = multimanager.get_kernel(multimanager.start_kernel("python3"))
client = manager.client()
time.sleep(0.5)
print(client.iopub_channel.get_msgs())
client.shutdown()
time.sleep(0.5)
print([m["header"]["msg_type"] for m in client.iopub_channel.get_msgs()])

However, the following code does not reproduce the issue:

multimanager = MultiKernelManager()
manager = multimanager.get_kernel(multimanager.start_kernel("python3"))
client = manager.client()
client.shutdown()
print(client.get_shell_msg())
print(client.get_iopub_msg())

Instead, it just blocks on get_iopub_msg, after returning the shutdown_reply message on the shell channel.

Can you help me figure out what's going on? Is the shutdown_reply being sent on both channels? Why is it being received on iopub at all?

I am quite confused. (The real issue I'm having is on a Haskell codebase, but hopefully these code snippets are enough to reproduce it.)

Here are some versions:

Python 3.5.0 (default, Oct  3 2015, 11:20:34)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ipykernel; print(ipykernel.__version__)
4.3.1
>>> import jupyter_client; print(jupyter_client.__version__)
4.3.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions