A process that ignores SIGTERM cannot hold shutdown hostage forever. Once the grace period elapses, any service still stopping gets SIGKILL - the signal it cannot catch. Today you add that escalation at the exact deadline.
After the grace deadline passes, send SIGKILL to any service still Stopping.
SIGTERM is a request a process can ignore - and some do, whether wedged in a tight
loop, mid-flush, or simply buggy. A supervisor that waited indefinitely for them
would never finish shutting down, so it escalates. Once the grace deadline recorded
at shutdown has passed, every service still stuck in Stopping is sent SIGKILL,
the one signal a process cannot catch, block, or ignore - the kernel tears it down.
This SIGTERM-then-SIGKILL escalation is exactly what systemd’s
TimeoutStopSec and a normal kill followed by kill -9 do.
The deadline is the boundary to pin precisely. Before it, KillOverdue does nothing
t=4s (grace is 5s) sends no signal, while a pass at exactly
t=5s sends SIGKILL to whatever is still stopping. And a service that already exitedStopped before the deadline - is gone and never gets killed. With this,
the shutdown path is complete: signal in reverse order, wait out the grace, and force
the stragglers. Everything is now in place for the capstone.func (s *Supervisor) KillOverdue() {if s.clock.Now() < s.deadline { return } // grace not yet elapsedfor _, name := range s.Names() {svc, _ := s.Get(name)if svc.State == Stopping {s.rt.Signal(svc.Handle, SIGKILL) // cannot be caught or ignored}}}