Skip to content

Cancel run_r's later callbacks so the loop drains - #268

Merged
simonpcouch merged 2 commits into
mainfrom
jat255/267-cancel-later-timers
Sep 5, 2026
Merged

Cancel run_r's later callbacks so the loop drains#268
simonpcouch merged 2 commits into
mainfrom
jat255/267-cancel-later-timers

Conversation

@jat255

@jat255 jat255 commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Fixes #267.

To be completely honest, this is touching R code and mechanics in a way I totally do not understand, so this fix is totally on Claude. @simonpcouch please take a look over the approach and double-check it makes sense? Thanks!

Every run_r_tool() call armed two later callbacks and cancelled neither, and worker_close() didn't either. shiny::testServer() spins until later::loop_empty(), so after test-run-r.R the loop held 70 callbacks, the farthest 601 seconds out, and the first testServer() block in test-trajectory-review.R blocked for 601.1s. That was most of the 15-minute CI job.

later() and later_fd() return canceller functions (there is no later::cancel()). The change, all in pkg-r/R/run-r.R:

  • Keep cancellers for the call timeout, kill escalation, and later_fd() watcher in worker_await(), and release them all from settle(): a finished call leaves nothing on the loop.
  • Hold one reap timer per worker instead of one per call, and cancel it in worker_close(). Reap timing and target selection are unchanged.
  • Interrupt and kill paths are untouched: callbacks are cancelled only once settled is TRUE, at which point they would have returned early anyway.

Verification: the new test in test-run-r.R fails before the change and passes after; the viewer test went from 601.1s to 0.65s; R CMD check is 1m17s, Status: OK, no notes. Full suite passes locally in 52s (28 skips, all environmental). No tests deleted; one added.

The CI tests drop from about 15m for the "R CMD check" job to ~5m.

Worth your scrutiny:

  • The ordering in poll(), where the callback clears cancel_watch and may re-arm it through a recursive poll() call. I am confident it is right but it is the fiddliest part.
  • Whether cancelling the reap timer on every call, rather than letting redundant timers pile up and no-op, is the behaviour you want for a long-lived worker under steady load.

Every run_r_tool() call armed a reap timer at commons.run_r_idle_timeout + 1
(601 seconds by default) and a timeout timer at commons.run_r_timeout (60
seconds), and nothing cancelled either one. worker_close() did not cancel
them either.

shiny::testServer() reads outputs through shiny:::wait_for_it(), which spins
until later::loop_empty() rather than waiting on the output's own promise.
After test-run-r.R the global loop held 70 callbacks, the farthest 600.9
seconds out, so the first testServer() block in test-trajectory-review.R that
read an output blocked for 601.1 seconds. R CMD check reported the tests as
[2m/11m]: two minutes of CPU, eleven minutes of wall clock.

later::later() and later::later_fd() each return a canceller. Keep the
handles, release them when the call settles, hold one reap timer per worker
instead of one per call, and cancel it in worker_close().

The viewer test now takes 0.65 seconds and the whole suite 52 seconds.

Fixes #267
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Preview deployed to Connect (dogfood.team.pct.posit.it): https://dogfood.team.pct.posit.it/connect/#/apps/d7a36cae-8f27-448b-a478-61b81fbe3942/draft/368055

Deployed from commit d469b4c.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

Preview deployed to Connect (connect.staging.pct.posit.it): https://connect.staging.pct.posit.it/connect/#/apps/ad662e1b-5048-4acc-9ad7-f9478c92274e/draft/2600

Deployed from commit d469b4c.

@jat255
jat255 requested a review from simonpcouch September 4, 2026 03:38
@jat255 jat255 added the r Affects the R implementation label Sep 4, 2026

@simonpcouch simonpcouch left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would have thought that this could be achieved without changes in R/, and the double assignment gives me the heebie jeebies a bit. Sorry to not approve and also not have the bandwidth to really look into this—planning to spend some time on commons tomorrow and will see what I can do here then!

@simonpcouch

Copy link
Copy Markdown
Collaborator

In the meantime, feel free to ignore the R CMD check GHA.

@jat255

jat255 commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author

I would have thought that this could be achieved without changes in R/, and the double assignment gives me the heebie jeebies a bit. Sorry to not approve and also not have the bandwidth to really look into this—planning to spend some time on commons tomorrow and will see what I can do here then!

Totally understandable. I'll ask Claude to take another look to see if it's fixable on the test side only. It seemed convinced this was the right way, but I also didn't push back.

@simonpcouch simonpcouch left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

F****** ASYNC

Okay, yes, I'm on board. Thanks for your patience :) Just sent up some small changes to avoid some of the double assignments and simplify cancellation.

Thanks for catching this! I see that tests now wrap up in ~50s or so locally. We could also test in parallel--will file an issue to do so.

@simonpcouch
simonpcouch merged commit 56de469 into main Sep 5, 2026
3 of 4 checks passed
@simonpcouch
simonpcouch deleted the jat255/267-cancel-later-timers branch September 5, 2026 15:05
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Cleaned up 2 preview bundle(s) on https://dogfood.team.pct.posit.it: 367611, 368055

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Cleaned up 1 preview bundle(s) on https://connect.staging.pct.posit.it: 2545

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r Affects the R implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

run_r leaks later timers, which stalls the R test suite for ten minutes

2 participants