Skip to content

Commit 88ad698

Browse files
Merge pull request #91 from davidbrochart/sub-shells
Add JEP for sub-shells
2 parents 1eb523a + 5f8bf40 commit 88ad698

File tree

1 file changed

+192
-0
lines changed

1 file changed

+192
-0
lines changed

kernel-subshells/kernel-subshells.md

+192
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
---
2+
title: Jupyter kernel subshells
3+
authors: David Brochart (@davidbrochart), Sylvain Corlay (@SylvainCorlay), Johan Mabille (@JohanMabille), Ian Thomas (@ianthomas23)
4+
issue-number: XX
5+
pr-number: 91
6+
date-started: 2022-12-15
7+
---
8+
9+
# Summary
10+
11+
This JEP introduces kernel subshells to allow for concurrent shell requests.
12+
13+
# Motivation
14+
15+
Users have been asking for ways to interact with a kernel while it is busy executing CPU-bound code,
16+
for the following reasons:
17+
- inspect the kernel's state to check the progress or debug a long-running computation (e.g.
18+
through a variable explorer).
19+
- visualize intermediary results before the final result is computed.
20+
- request [completion](https://jupyter-client.readthedocs.io/en/stable/messaging.html#completion) or
21+
[introspection](https://jupyter-client.readthedocs.io/en/stable/messaging.html#introspection).
22+
- process
23+
[Comm messages](https://jupyter-client.readthedocs.io/en/stable/messaging.html#custom-messages)
24+
immediately (e.g. for widgets).
25+
- execute arbitrary code in parallel.
26+
27+
It is currently not possible to do so because the kernel processes shell requests sequentially.
28+
Since the control channel has had its own thread it has been possible to use the control channel
29+
for such interactions, but this is considered bad practice as it should only be used for control
30+
purposes, and the processing of those messages should be almost immediate.
31+
32+
The goal of this JEP is to offer a way to process shell requests concurrently.
33+
34+
# Proposed enhancement: kernel subshells
35+
36+
The proposal is to support extra threads within a kernel as a JEP 92
37+
[optional feature](https://github.com/jupyter/enhancement-proposals/blob/master/92-jupyter-optional-features/jupyter-optional-features.md) so that whilst the main thread is performing a long blocking task it
38+
will be possible for other threads to do something useful within the same process namespace.
39+
40+
When a kernel that supports subshells is started it will have a single subshell and this is referred
41+
to as the parent subshell to distinguish it from the other optional subshells which are referred to
42+
as child subshells.
43+
44+
A new child subshell thread is started using a new `create_subshell_request` control message rather
45+
than via the REST API. Each subshell has a `subshell_id` which is a unique identifier within that
46+
kernel. The `subshell_id` of a child subshell is generated when the subshell is created and
47+
returned in the `create_subshell_reply` message. The parent subshell has a `subshell_id` of `None`.
48+
[Shell messages](https://jupyter-client.readthedocs.io/en/stable/messaging.html#messages-on-the-shell-router-dealer-channel)
49+
include the `subshell_id` as an optional field in the message header to indicate which subshell the
50+
message should be sent to; if this is not specified or is `None` then the parent
51+
subshell is targeted. Use of a `subshell_id` that is not recognised will raise an error.
52+
Subshells are thus multiplexed on the shell channel through the `subshell_id`, and it is the
53+
responsibility of the kernel to route the messages to the target subshell according to the
54+
`subshell_id`.
55+
56+
Note a kernel that does not support `subshell_id` will just ignore the field if it is present and
57+
run in the main thread.
58+
59+
[Stdin messages](https://jupyter-client.readthedocs.io/en/stable/messaging.html#messages-on-the-stdin-router-dealer-channel)
60+
will also include the extra optional `subshell_id` field so that it is possible for a subshell to
61+
request and receive stdin independently of other subshells.
62+
63+
Each subshell will store its own execution count and history.
64+
65+
## Modifications to existing messages
66+
67+
### Identify optional feature
68+
69+
Clients identify if a kernel supports subshells via the
70+
[optional feature API](https://github.com/jupyter/enhancement-proposals/blob/master/92-jupyter-optional-features/jupyter-optional-features.md):
71+
72+
Message type: `kernel_info_reply`:
73+
74+
```py
75+
content = {
76+
...
77+
'supported_features': [
78+
'kernel subshells',
79+
...
80+
]
81+
}
82+
```
83+
84+
The full API for optional features is still to be determined, so the details here may change.
85+
In particular, there is probably the need for a version specifier here to allow future changes to
86+
the kernel subshells specification.
87+
88+
## New control channel messages
89+
90+
### Create subshell
91+
92+
Message type: `create_subshell_request`: no content.
93+
94+
Message type: `create_subshell_reply`:
95+
96+
```py
97+
content = {
98+
# 'ok' if the request succeeded or 'error', with error information as in all other replies.
99+
'status': 'ok',
100+
101+
# The ID of the subshell.
102+
'subshell_id': str,
103+
}
104+
```
105+
106+
### Delete subshell
107+
108+
Message type: `delete_subshell_request`:
109+
110+
```py
111+
content = {
112+
# The ID of the subshell.
113+
'subshell_id': str
114+
}
115+
```
116+
117+
Message type: `delete_subshell_reply`:
118+
119+
```py
120+
content = {
121+
# 'ok' if the request succeeded or 'error', with error information as in all other replies.
122+
'status': 'ok',
123+
}
124+
```
125+
126+
### List subshells
127+
128+
Message type: `list_subshell_request`: no content.
129+
130+
Message type: `list_subshell_reply`:
131+
132+
```py
133+
content = {
134+
# A list of subshell IDs.
135+
'subshell_id': [str]
136+
}
137+
```
138+
139+
Note that the parent subshell (`subshell_id = None`) is not included in the returned list.
140+
141+
## New fields on existing messages
142+
143+
### Shell and stdin requests
144+
145+
All shell and stdin messages will allow the optional `subshell_id` field in the request to identify
146+
which subshell should process that message:
147+
148+
```py
149+
content = {
150+
# Optional subshell to process request.
151+
'subshell_id': str | None,
152+
}
153+
```
154+
155+
This field is not in the corresponding reply message as it will be in the parent header.
156+
157+
### IOPub messages
158+
159+
IOPub messages do not need an extra optional `subshell_id` field as this information is available
160+
in the parent header.
161+
162+
## Behavior
163+
164+
### Kernels supporting subshells
165+
166+
A subshell request may be processed concurrently with other subshells. Within a an individual
167+
subshell, requests are processed sequentially.
168+
169+
[Kernel shutdown](https://jupyter-client.readthedocs.io/en/stable/messaging.html#kernel-shutdown)
170+
and [kernel interrupt](https://jupyter-client.readthedocs.io/en/stable/messaging.html#kernel-interrupt)
171+
messages are handled at the kernel (process) rather than subshell (thread) level, and they do not
172+
include a `subshell_id` field. A child subshell can be individually shut down using a
173+
`delete_subshell_request` message.
174+
175+
### Kernels not supporting subshells
176+
177+
These will not claim support for kernel subshells via the optional features API. Unrecognised shell
178+
request messages, such as the subshell request messages listed above, will be ignored as normal.
179+
Any use of a `subshell_id` field in a message will be ignored. Hence existing kernels that do not
180+
support kernel subshells will continue to work as they currently do and will not require any
181+
changes.
182+
183+
## Implications for other projects
184+
185+
Kernel writers who wish to support subshells will need to write extra threading and socket
186+
management code. `ipykernel` will contain a reference implementation.
187+
188+
Any client that wishes to create a subshell will have to issue a `create_subshell_request` control
189+
message, and pass the `subshell_id` in all relevant shell and stdin messages.
190+
191+
There will need to be some sort of visual indicator for subshells in, for example, the JupyterLab
192+
UI, but this is not strictly speaking part of the JEP.

0 commit comments

Comments
 (0)