fix(jupyter): exit kernel process after sending shutdown reply (#34554)
## Summary
When Jupyter closes (e.g. `jupyter console --kernel deno` followed by
exit),
it sends a `shutdown_request` on the control channel. The kernel
responds
with `shutdown_reply` and calls `cancel_handle.cancel()` — but the
kernel
process keeps running in the background:
```
$ jupyter console --kernel deno
...
Do you really want to exit ([y]/n)? y
Shutting down kernel
Client disconnected PeerIdentity(...)
$ ps aux | grep "deno" | grep "jupyter"
matt 65952 ... /Users/matt/.../deno --unstable jupyter --kernel --conn ...
```
Cancelling the server loop is not enough on its own: the
heartbeat/shell/
stdio futures are spawned tasks whose `JoinHandle`s being dropped does
not
abort the underlying tasks, and the worker thread driving the V8 isolate
on the main thread isn't woken up to exit either. The result is an
orphaned `deno jupyter --kernel` process every time Jupyter closes.
The Jupyter messaging protocol expects the kernel to exit after sending
a
shutdown reply, so do that explicitly. A brief sleep before exiting
gives
ZMQ a chance to flush the reply over TCP first.
Closes #20556.
Closes denoland/orchid#291.
## Test plan
- [x] `cargo test --test integration jupyter::` (9/9 pass;
`jupyter_shutdown_reply` and `jupyter_shutdown_restart_reply` both
finish in <1s)
- [x] Removed the stale comment in `JupyterServerProcess::wait_or_kill`
that called out the kernel "doesn't seem to exit in a reasonable amount
of time after getting a shutdown request" — that's no longer true with
this fix.
Co-authored-by: divybot <divybot@users.noreply.github.com>
Co-authored-by: Divy Srivastava <me@littledivy.com>