Skip to content

feat: add graceful shutdown via SIGTERM/SIGINT#67

Draft
toddr-bot wants to merge 1 commit into
mainfrom
koan.toddr.bot/graceful-signal-shutdown
Draft

feat: add graceful shutdown via SIGTERM/SIGINT#67
toddr-bot wants to merge 1 commit into
mainfrom
koan.toddr.bot/graceful-signal-shutdown

Conversation

@toddr-bot
Copy link
Copy Markdown

@toddr-bot toddr-bot commented Apr 15, 2026

What

Bind() now handles SIGTERM and SIGINT gracefully instead of dying immediately.

Why

Previously, sending SIGTERM to a Net::Daemon process killed it without cleanup — the "Server terminating" log never fired, sockets weren't closed, and the process gave no indication of an orderly shutdown. This is the expected behavior for any production daemon.

Also, the $Net::Daemon::exit variable was declared but never actually used — the preforking parent's signal handlers used die instead. This wires up the original design.

How

  • Install $SIG{TERM} and $SIG{INT} handlers in Bind() that call $self->Done(1), breaking the accept loop naturally via the existing while (!$self->Done()) condition.
  • In preforking mode, signal handlers now set $exit = 1 instead of die — cleaner and consistent with the variable's intended purpose.
  • POD documents the signal handling behavior and how subclasses can customize it.

Testing

  • New t/signal.t with 6 tests: fork-based tests for both SIGTERM and SIGINT graceful shutdown (pipe-synchronized), plus direct Done() flag verification.
  • Full test suite passes (82 subtests across 19 test files).

🤖 Generated with Claude Code


Quality Report

Changes: 2 files changed, 172 insertions(+), 2 deletions(-)

Code scan: clean

Tests: passed (OK)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

Bind() now installs SIGTERM and SIGINT handlers that set the Done flag,
allowing the accept loop to exit cleanly. Previously, these signals
killed the daemon immediately — the "Server terminating" log message
never fired and sockets were not properly closed.

Also fixes the preforking parent to use $exit flag instead of die in
signal handlers, which is cleaner and actually uses the $exit variable
as originally designed.

Adds t/signal.t with pipe-synchronized fork tests verifying both
SIGTERM and SIGINT trigger graceful shutdown.

Co-Authored-By: Claude Opus 4.6 <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.

1 participant