diff --git a/authbridge/cmd/abctl/cmd_service_platform.go b/authbridge/cmd/abctl/cmd_service_platform.go index a37d491d3..778e3aa83 100644 --- a/authbridge/cmd/abctl/cmd_service_platform.go +++ b/authbridge/cmd/abctl/cmd_service_platform.go @@ -128,6 +128,13 @@ func renderUnitFor(goos string, p servicePaths) string { // No After=network-online.target: that target is not part of a user manager, and // every listener here is loopback, so ordering against the network would be a // dependency that never arrives. + // + // TimeoutStopSec=20: narrows systemd's own default (90s) down toward the proxy's + // 15s shutdown deadline (cmd/authbridge-proxy/main.go), rather than adding headroom + // to nothing — matches the macOS supervisor's 20s wait for the same shutdown + // (supervise.go). 15s bounds the HTTP servers and pipelines specifically; a couple + // of unbounded flushes run after that deadline, which is what the 5s of slack over + // 15 is actually for. return `[Unit] Description=Cortex local proxy (authbridge-proxy) Documentation=https://github.com/rossoctl/cortex @@ -140,6 +147,7 @@ Type=simple ExecStart=` + shQuote(p.binary) + ` --config ` + shQuote(p.configFile) + ` Restart=on-failure RestartSec=10 +TimeoutStopSec=20 StandardOutput=append:` + p.logFile + ` StandardError=append:` + p.logFile + ` diff --git a/authbridge/cmd/abctl/cmd_service_test.go b/authbridge/cmd/abctl/cmd_service_test.go index fc5e6aec8..029e24c1a 100644 --- a/authbridge/cmd/abctl/cmd_service_test.go +++ b/authbridge/cmd/abctl/cmd_service_test.go @@ -80,6 +80,14 @@ func TestRenderUnit_BothPlatforms(t *testing.T) { t.Errorf("unit missing %q:\n%s", want, u) } } + // TimeoutStopSec must exceed the proxy's own 15s graceful-shutdown deadline + // (cmd/authbridge-proxy/main.go), explicitly — not by accident of whatever + // systemd's own default happens to be. See the rationale comment above + // renderUnitFor's linux branch. + if !strings.Contains(u, "TimeoutStopSec=20\n") { + t.Error("TimeoutStopSec is missing or not 20; stop relies on an unasserted " + + "value, which could end up shorter than the proxy's 15s drain") + } // StartLimit* must sit in [Unit]. systemd moved them there in v229 and // deprecated them in [Service], where they can be ignored outright — // silently voiding the crash-loop throttle.