Skip to content

fix: Stop Connect containers promptly by signaling Connect directly - #71

Merged
nealrichardson merged 2 commits into
mainfrom
fast-stop
Oct 23, 2026
Merged

nealrichardson merged 2 commits into
mainfrom
fast-stop

Conversation

@nealrichardson

Copy link
Copy Markdown
Collaborator

Fixes #56.

Problem

The modern ghcr.io/posit-dev/connect image runs startup.sh as PID 1, with no SIGTERM trap and no exec. A shell running as PID 1 ignores SIGTERM, so container.stop() waits out Docker's grace period (10 seconds by default) and then SIGKILLs the container. That happens on every --stop and at the end of every command-mode run. The legacy rstudio/rstudio-connect images don't have this problem, because tini forwards the signal.

Fix

stop_connect_container() runs pkill -TERM -f '^/opt/rstudio-connect/bin/connect( |$)' inside the container and waits up to 10 seconds for the container to exit. If pkill doesn't match, isn't installed, or Connect doesn't exit in time, it falls back to container.stop(timeout=2). This is the stop part of #53, adapted to how with-connect runs Connect without a keep-alive process.

Both stop paths use it: --stop and the cleanup in main(). I also removed an extra container.stop() in wait_for_http_server(), because the finally in main() already stops the container on that path.

Verification

  • The pattern matches only the Connect server process, not rserver-monitor or other children. It also matches under Rosetta on Apple Silicon.

  • Using throwaway containers on the modern image:

    time exit code
    container.stop() killed after the grace period 137 (SIGKILL)
    stop_connect_container() 0.4 s 0, and Connect logs its own shutdown

    On my machine Docker gave containers a 1-second stop timeout, so the plain stop took about 1.2 s instead of the ~11 s in the issue. The fast stop also means Connect shuts down cleanly instead of being SIGKILLed.

  • On the legacy jammy image, signaling Connect directly exits cleanly in 0.27 s.

  • Unit tests cover the helper (signaling Connect, pkill not matching or not installed, exec errors, wait timeouts) and both stop paths through main().

Merging with #70

This branch merges cleanly with #69. It has one small conflict with #70 in the finally cleanup: keep #70's try/except warning and call stop_connect_container(container) inside it.

🤖 Generated with Claude Code

nealrichardson and others added 2 commits October 23, 2026 09:51
Newer images run startup.sh as PID 1, which ignores SIGTERM, so stopping
the container waited out Docker's 10 second grace period before killing
it. with-connect sends SIGTERM to the Connect process instead, which shuts
down cleanly in under a second, and falls back to a 2 second stop timeout.

Fixes #56.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w it

Adds tests that stop Connect through main() in --stop and command mode.
Addresses roborev job 683.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--stop wastes 10 seconds every time

1 participant