fix: run coordinator shutdown on SIGINT and SIGTERM

Merged
RE
21d ago
+41-2

Summary

Standalone dagu coordinator had no signal handler. SIGINT and SIGTERM hit the Go runtime default and killed the process before Service.Stop could run, so the registry entry stayed behind.

Changes

  • runCoordinator waits on notifyShutdownContext for SIGINT and SIGTERM, the same helper server and start-all use.
  • It calls stop() before cleanup, so a second SIGINT ends the process and a repeated SIGTERM stays absorbed, as in #2966.
  • Service.Stop gets the parent context, because the signal context is already canceled and Stop passes its context to handler.Close.
  • TestCoordinatorSignalShutdown in signal_unix_test.go starts the built binary, waits for registration, sends each signal, and checks for a clean exit and an empty coordinator registry directory.

Related Issues

Closes #2956

Checklist

  • Code follows the project style guidelines
  • Self-review of the code has been performed
  • Tests have been added or updated as needed
  • Documentation has been updated as needed (not needed)
  • Changes have been tested locally

Testing

I work on Windows, and the new test is Unix only. I cross-compiled the binary and the internal/cmd test binary for linux/amd64 and ran them under WSL Ubuntu.

  • Before the fix, TestCoordinatorSignalShutdown fails with signal: terminated and signal: interrupt. After the fix, both subtests pass, and so do TestCoordinatorCommand and TestRepeatedTerminateDuringRunCleanup.
  • The reproduction script from the issue now gives exit=0. It logs Coordinator shutting down and Unregistered from service registry, and the registry file is removed.
  • golangci-lint v2.13.2 reports 0 issues in internal/cmd for linux and windows.

The test covers signal handling and registry removal. It does not exercise open attempts or active RPC draining during shutdown.


Summary by cubic

Fixes the standalone dagu coordinator dying on SIGINT/SIGTERM before shutdown cleanup, leaving its registry entry behind. The coordinator now unregisters from the service registry cleanly on signal. Closes #2956.

  • Waits on the same signal context helper the server and start-all commands use.
  • A second SIGINT aborts shutdown; repeated SIGTERMs stay absorbed.
  • Service.Stop receives the parent context because the signal context is already canceled.
  • Adds a Unix-only test that signals the built binary and verifies a clean exit with an empty registry directory.

Summary by CodeRabbit

  • Bug Fixes
    • Coordinator shutdown now handles SIGINT and SIGTERM more reliably, stopping the service and removing its registry entry before exiting.
    • A second SIGINT can interrupt the shutdown process, while SIGTERM is absorbed so cleanup can proceed.
    • These changes help ensure the coordinator exits successfully and leaves no stale registry entry after receiving a termination signal.