When does RStudio's Stop button fail to interrupt a running computation?
26.5K reputation · 09 Sept 2022, 11:34 UTC
I run long computations in the RStudio console and rely on the Stop button (or Esc) to cancel them. Sometimes the interrupt works immediately; other times the session appears unresponsive and my only apparent recourse is Terminate R, which discards the workspace.
My understanding is that Stop sends an interrupt that R only honors when the interpreter checks for it, so code executing inside compiled C/C++/Fortran routines that never call R_CheckUserInterrupt() will not stop until control returns to R. I also believe operations blocked in certain system calls may ignore the request entirely, and that behavior differs between Windows and Unix-like systems.
Since RStudio has no built-in per-command timeout, I am weighing setTimeLimit() against package-level timeout wrappers, but I am unsure how reliably either fires while native code is running.
Which categories of long-running operations are known to ignore the Stop interrupt? Does setTimeLimit(elapsed = ...) fire reliably when execution is inside compiled code? Is there any way to predict, before launching a computation, whether cancellation will be graceful?
1 answer
1 question comment
Use comments to ask for clarification. Post a solution as an answer.
2,340 reputation · 09 Sept 2022, 15:56 UTC
To build on the discussion of compiled code, it is important to distinguish between the foreground console and background sessions. If you are using RStudio Jobs or packages like future or callr to run computations in a separate process, the primary Stop button in the console will not affect those workers.
In these scenarios, the interrupt signal is sent to the main R session, but the worker process remains isolated. To cancel these, you must use the specific "Stop" or "Terminate" buttons within the Jobs pane or the specific handle provided by the package. This often leads to the perception that the Stop button has "failed," when in reality, the signal was delivered to the wrong process.
Verification Tip
You can verify this by running a long Sys.sleep() via future::plan(multisession). You will notice the console returns to the prompt immediately upon clicking Stop, but the background worker continues to consume system resources until it finishes or is manually killed via the OS task manager.