Per-cell execution timeout remains absent in JupyterLab 4.x despite kernel interruption and idle culling mechanisms
0 reputation · 02 Nov 2021, 04:38 UTC
0 reputation · 02 Nov 2021, 04:38 UTC
Jupyter Server 2.x introduced KernelManager.cull_connected to control whether kernels with active frontend connections but no recent code execution are culled, complementing the existing cull_idle_timeout and cull_interval settings. However, these idle-culling parameters only affect kernels that have gone completely inactive; they do not interrupt a cell that is actively executing, even if that execution exceeds any reasonable time bound.
The Jupyter protocol defines an interrupt_request message, yet the kernel's response is implementation-dependent. IPython converts it to a KeyboardInterrupt at the next bytecode boundary, while kernels running native extensions or blocking system calls may ignore the signal entirely. No core JupyterLab 4.x feature enforces a maximum cell execution time, and third-party extensions such as jupyterlab-execution-timeout rely on kernel-specific APIs that do not generalize across kernel types.
cull_connected setting interact with long-running cells that maintain active frontend connections but produce no output?35275 reputation · 02 Nov 2021, 07:49 UTC
No. JupyterLab 4.x with Jupyter Server 2.x does not enforce a maximum wall-clock time for an individual cell. cull_idle_timeout, cull_interval, and cull_connected manage kernel lifecycle; they do not interrupt code that is actively executing. The interrupt_request message exists in the protocol, but whether it stops a cell depends on the kernel, so there is no cross-kernel per-cell timeout built into JupyterLab 4.x.
cull_connected concerns a kernel with an active frontend connection but no recent execution; a cell currently running is not idle merely because it emits no output.interrupt_request into KeyboardInterrupt at the next bytecode boundary.Execution happens inside the kernel process, while JupyterLab is a frontend. The frontend cannot enforce a wall-clock deadline without kernel cooperation, an out-of-process supervisor, or kernel restart. No widely adopted message-specification standard is known to define per-cell execution timeouts; treat that as needing review.
python -m jupyterlab --version and python -m jupyter_server --version. List kernels with jupyter kernelspec list.cull_idle_timeout, cull_interval, and cull_connected. None of these defines a per-cell execution limit.time.sleep(300) in an IPython notebook cell, choose Kernel → Interrupt, and confirm execution stops. Repeat with any native extension or blocking call used in production cells.What is the target kernel language, and do the long-running cells call native extensions or blocking system calls? This determines whether interrupt_request is reliable or whether you need kernel restart or external supervision.
After any workaround, measure elapsed time from cell start to interruption or restart, and confirm whether in-memory variables survive. Restart-based enforcement should be used only when state loss is acceptable.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 02 Nov 2021, 15:04 UTC
The Jupyter interrupt_request message delivery depends on kernel implementation: IPython translates it to a KeyboardInterrupt at the next bytecode boundary, while kernels running native extensions or blocking system calls may defer or entirely ignore the signal. Consequently, cull_connected in Jupyter Server 2.x only targets kernels whose frontends have been inactive with no recent execution; it cannot interrupt a cell mid-computation, even when a frontend connection persists. For reliable per-cell timeouts across kernel types, server-side watchdog processes or extension hooks that poll cell execution state and issue targeted interrupt_request messages at configurable boundaries are currently the most portable approach, though they require kernel-specific handling and may trigger unexpected restarts if interrupt handlers are not gracefully implemented.