Skip to content

Add SIGTERM handling at tracker signal boundary #2132

Description

@josecelano

Parent

Part of #1488.

Goal

Handle SIGTERM in src/main.rs alongside the existing SIGINT handler so kill <pid>, docker stop, systemctl stop, and Kubernetes pod termination start the existing coordinated graceful-shutdown sequence.

Background

main.rs currently waits only for tokio::signal::ctrl_c(). SIGTERM, the default signal sent by kill, container runtimes, and service managers, bypasses main.rs; consequently, it does not invoke jobs.cancel() or jobs.wait_for_all(...). Server libraries currently retain independent legacy signal subscriptions. That temporary duplicate reaction is expected and must remain untouched in this slice.

Scope

  • Register a Unix-only Tokio SIGTERM listener with tokio::signal::unix::signal(SignalKind::terminate()).
  • Use one tokio::select! to determine whether SIGINT or SIGTERM requested shutdown.
  • Log Torrust tracker shutting down (SIGINT) ... or Torrust tracker shutting down (SIGTERM) ..., then run the existing sequence exactly once: jobs.cancel(), jobs.wait_for_all(Duration::from_secs(10)).await, and completion logging.
  • Preserve tokio::signal::ctrl_c() support on Windows without adding Windows service-control-manager work.
  • Preserve the startup-error path.
  • Move and maintain the local issue specification and raw verification evidence under docs/issues/open/2132-add-sigterm-to-main/.

Out of scope

  • JobManager ownership, JoinSet, concurrency, deadline, or exit-result changes (Adopt JoinSet supervision in JobManager #1586 and SI-20).
  • Periodic-job token migrations (SI-4 and SI-5).
  • Legacy global_shutdown_signal() or server API removal (SI-2 and later).
  • Axum drain, UDP lifecycle, readiness, SIGHUP, profiling, and Windows SCM work.

Acceptance criteria

  • kill <tracker-binary-pid> starts the coordinated shutdown sequence and logs the SIGTERM source.
  • kill -TERM <tracker-binary-pid> has the same outcome.
  • SIGINT still starts the sequence and logs SIGINT, not SIGTERM.
  • SIGTERM runs cancellation and named JobManager waiting after the source log.
  • Unix-only signal registration is conditionally compiled; Windows retains Ctrl+C support only.
  • Verification targets ./target/release/torrust-tracker directly, not cargo run.
  • Verification permits the current sequential legacy per-job shutdown behavior; SI-20 owns final deadline policy.
  • cargo test and linter all pass.

Verification

Build the release binary, launch ./target/release/torrust-tracker directly in the background while recording its PID and logs, wait for a deterministic startup indication, and run separate default-SIGTERM, explicit-SIGTERM, and SIGINT checks. Record complete raw terminal and log output in the local verification evidence. Do not use timeout 20s cargo run as signal-boundary evidence. SIGKILL is only a baseline/control, not a normal stop mechanism.

References

  • Overhaul: Tracker Shutdown #1488
  • docs/issues/open/2132-add-sigterm-to-main/ISSUE.md
  • docs/issues/open/2132-add-sigterm-to-main/verification.md
  • docs/features/shutdown-process/questions.md (Q1, Q5, Q7, and Q9)
  • docs/adrs/20260902074438_adopt_supervised_cancellation_tree_for_shutdown.md

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions