Files
reverse-proxy/tasks/ops/signals-and-shutdown.md
glm-5.1 309878c561 Decompose architecture into 23 atomic tasks across 7 parallel generations
Task graph covers all Phase 1 concerns: config system, TLS termination,
proxy handler, operations (rate limiting, logging, health check, admin
socket, signals, shutdown, body size limit), deployment artifacts, and
two review checkpoints.

No circular dependencies. Critical path length of 7. Risk distribution:
3 high-risk (ACME, TLS listener setup, startup orchestration), 7 medium,
11 low, 2 trivial.
2026-06-11 11:21:10 +00:00

2.8 KiB

id, name, status, depends_on, scope, risk, impact, level
id name status depends_on scope risk impact level
ops/signals-and-shutdown Implement signal handling (SIGTERM/SIGINT/SIGHUP) and graceful shutdown sequence pending
config/dynamic-config
ops/admin-socket
moderate medium component implementation

Description

Implement signal handling for SIGTERM, SIGINT, and SIGHUP, plus the graceful shutdown sequence.

Signal Handling

Using signal-hook crate (per ADR-009):

  • SIGTERM / SIGINT: Graceful shutdown
  • SIGHUP: Config reload (same code path as admin socket reload command)

Graceful Shutdown Sequence

On SIGTERM or SIGINT:

  1. Stop accepting new connections — Close all TCP listening sockets
  2. Close idle keep-alive connections — Send Connection: close on idle connections
  3. Wait for in-flight requests — Up to shutdown_timeout_secs (default: 30)
  4. Force-close remaining connections — After timeout, TCP RST
  5. Cancel background tasks — ACME renewal, rate limiter eviction, admin socket
  6. Exit with code 0

SIGHUP for Config Reload

SIGHUP triggers the same config reload as the admin socket reload command:

  1. Re-read the config file from disk
  2. Deserialize into full config (static + dynamic)
  3. Validate the full config
  4. If valid: swap DynamicConfig, log warnings for any static changes
  5. If invalid: reject reload, log error, keep old DynamicConfig

SIGHUP provides no feedback on success or failure — it just logs. The admin socket is the programmatic alternative with structured responses.

Shutdown Timeout

Configurable via shutdown_timeout_secs in StaticConfig (default: 30 seconds).

Acceptance Criteria

  • signal-hook handles SIGTERM, SIGINT, SIGHUP
  • SIGTERM/SIGINT triggers graceful shutdown sequence
  • SIGHUP triggers config reload (same code path as admin socket)
  • Graceful shutdown: close listening sockets first
  • Graceful shutdown: close idle keep-alive connections
  • Graceful shutdown: wait for in-flight requests up to timeout
  • Graceful shutdown: force-close remaining connections after timeout
  • Cancel background tasks (ACME, eviction, admin socket) on shutdown
  • Exit code 0 on graceful shutdown
  • shutdown_timeout_secs configurable in StaticConfig
  • SIGHUP reload converges on same code path as admin socket reload
  • Integration test: send SIGTERM, verify graceful shutdown sequence

References

  • docs/architecture/operations.md — signal handling, shutdown sequence
  • docs/architecture/decisions/009-signal-handling.md — signal handling strategy

Notes

The shutdown sequence must be carefully ordered. Closing listening sockets before waiting for in-flight requests ensures no new connections arrive while existing ones drain.

Summary

To be filled on completion