Skip to content

feat(headless): handle SIGTERM/SIGHUP for graceful shutdown#124

Merged
eitsupi merged 4 commits intomainfrom
feat/headless-sigterm-sighup
Mar 20, 2026
Merged

feat(headless): handle SIGTERM/SIGHUP for graceful shutdown#124
eitsupi merged 4 commits intomainfrom
feat/headless-sigterm-sighup

Conversation

@eitsupi
Copy link
Copy Markdown
Owner

@eitsupi eitsupi commented Mar 20, 2026

Summary

  • Enable ctrlc's termination feature so the existing signal handler also triggers on SIGTERM and SIGHUP
  • This enables clean shutdown (PID file removal, socket cleanup) from systemd stop, docker stop, and nohup hangup
  • Add integration test verifying SIGTERM triggers graceful shutdown with PID file cleanup

Test plan

  • test_headless_sigterm_shutdown — sends SIGTERM and verifies graceful exit + PID file removal
  • All existing headless tests pass
  • Manual: arf headless --pid-file /tmp/arf.pid then kill <pid> — verify clean exit and PID file removed
  • Manual: docker stop on containerized arf headless — verify clean exit

🤖 Generated with Claude Code

eitsupi and others added 2 commits March 20, 2026 09:36
Enable ctrlc's "termination" feature so the signal handler also
triggers on SIGTERM and SIGHUP. This enables clean shutdown (PID file
removal, socket cleanup) from systemd stop, docker stop, and nohup
hangup.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@eitsupi eitsupi changed the title feat: handle SIGTERM/SIGHUP for graceful headless shutdown feat(headless): handle SIGTERM/SIGHUP for graceful shutdown Mar 20, 2026
@eitsupi eitsupi requested a review from Copilot March 20, 2026 09:40
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends arf headless shutdown handling so that process termination signals (SIGTERM/SIGHUP) trigger the same graceful shutdown path as Ctrl+C, enabling clean cleanup (PID file + IPC socket/session) when managed by systemd/docker/nohup.

Changes:

  • Enable ctrlc’s termination feature to handle SIGTERM/SIGHUP in addition to SIGINT.
  • Update headless startup comments to reflect expanded signal handling behavior.
  • Add a Unix-only integration test asserting SIGTERM causes graceful exit and PID file removal.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
crates/arf-console/tests/headless_tests.rs Adds SIGTERM integration test for graceful shutdown + PID file cleanup.
crates/arf-console/src/main.rs Documents that the existing shutdown handler now covers SIGTERM/SIGHUP (via ctrlc feature).
Cargo.toml Enables ctrlc crate termination feature at the workspace level.
CHANGELOG.md Documents the new graceful shutdown behavior on SIGTERM/SIGHUP.
Comments suppressed due to low confidence (1)

crates/arf-console/src/main.rs:494

  • The warning log still says "Could not set Ctrl+C handler" even though the handler is now used for SIGTERM/SIGHUP as well (via the termination feature). Updating the message to refer to a generic signal/shutdown handler would avoid misleading logs when SIGTERM/SIGHUP handling is the reason this path exists.
    // Set up signal handler for graceful shutdown.
    // With the "termination" feature, ctrlc also handles SIGTERM and SIGHUP,
    // enabling clean shutdown from systemd stop, docker stop, nohup hangup, etc.
    let shutdown_signal = shutdown.clone();
    if let Err(e) = ctrlc::set_handler(move || {
        shutdown_signal.store(true, Ordering::Release);
    }) {
        log::warn!("Could not set Ctrl+C handler: {}", e);
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Wait for "Headless mode ready" stderr message (printed after the
ctrlc handler is installed) instead of just the PID file, to avoid
a race where SIGTERM arrives before the handler is set up.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…exit detection

- Extract common signal test logic into assert_signal_graceful_shutdown helper
- Add SIGHUP test alongside SIGTERM
- Check try_wait() in readiness loop for early-exit fail-fast with diagnostics
- wait_for_exit now returns ExitStatus; tests assert clean exit code
- Include server output in panic messages for easier debugging

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@eitsupi eitsupi merged commit d87cd35 into main Mar 20, 2026
14 checks passed
@eitsupi eitsupi deleted the feat/headless-sigterm-sighup branch March 20, 2026 09:59
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.

2 participants