ipykernel icon indicating copy to clipboard operation
ipykernel copied to clipboard

Support subshells

Open davidbrochart opened this issue 3 years ago • 3 comments

This PR aims at implementing potential solutions to support "subshells" (see https://github.com/jupyter/jupyter_client/issues/806).

In this first commit, the main shell runs in its own thread (which is not the main thread). A subshell can be created through a subshell_request received on the shell channel. This creates a new thread for this subshell, identified by a subshell ID. A request targeting this subshell must specify its subshell_id in the metadata (if not specified, then the request is targeting the main shell). Shell messages are received in the main thread and handled in the thread corresponding to the shell ID (the ID of the main shell is main, the ID of a subshell is a UUID). Thus, it is always possible to receive shell messages, even if a shell request is being handled. This approach modifies the behavior of ipykernel in the following ways:

  • if cells are cooperative (i.e. they have a top-level await), then they can be executed concurrently, similarly to what akernel does.
  • because the main shell is not executed in the main thread, it can potentially have consequences on code that expects to run in the main thread.
  • the handling of side-effects (e.g. printing to stdout or stderr) currently makes the assumption that shell requests are received and handled one at a time, which is not the case anymore: the next shell request can be received while the previous one is being handled.

davidbrochart avatar Jun 14 '22 07:06 davidbrochart

In https://github.com/ipython/ipykernel/pull/955/commits/0bde221b630a76ac758a41c35c5bf964995330ec the processing of the main shell requests is done in the main thread, and the shell messages are received in a separate thread. I didn't implement sending the replies through a queue yet, so it's still not thread-safe.

davidbrochart avatar Jun 14 '22 15:06 davidbrochart

I added a test in https://github.com/ipython/ipykernel/pull/955/commits/a64cf72868f9053345ab19149e5e22222c2889bb which checks that execution in a subshell is done in parallel with execution in the main shell.

davidbrochart avatar Jun 15 '22 09:06 davidbrochart

Regarding the implementation with a new zmq channel, the advantages would be:

  • no usage of the Queue (which is a synchronization object and should be avoided if we follow the ZMQ coding guideline)
  • we could avoid a new shell_id field in the message, asking for a new shell would simply drop a new connection file, with everything identical to the already existing connection file but the new shell port number.

JohanMabille avatar Jun 15 '22 10:06 JohanMabille