Graceful shutdown ... isn't
frostmar opened this issue · comments
Description of Problem / Feature Request
cmd/clair/main.go
installs a signal handler (SIGINT only) to perform a graceful shutdown.
I don't think this is working as desired
Expected Outcome
I would have expected HTTP servers to stop accepting new connections, then a short grace period for in-flight requests to complete (exiting as soon as no requests are in flight), as a last resort terminating connections then exiting if any are still running when the grace period expires.
Actual Outcome
HTTP servers are shutdown immediately, with any in-flight HTTP requests being severed.
Recreate:
- start a local Postgres
- run a clair indexer locally:
go run ./cmd/clair/ -conf ./local-dev/clair/config-frostmar-local.yaml -mode indexer
- start a long-running HTTP request, eg an indexing operation
curl -H "Content-Type: application/json" http://localhost:6060/indexer/api/v1/index_report -d ...<snipped>...
- send SIGINT - [CTRL+C] the
go run
command, orkill -INT <pid>
=> logs outputgracefully shutting down component=main signal=interrupt
=> process immediately exits
=> curl request immediately gives errorcurl: (52) Empty reply from server
I'd hope to see:
=> logs to output gracefully shutting down component=main signal=interrupt
=> 10 sec grace-period timeout
=> process exits only after the grace period
=> logs to output unregistered signal handler
=> curl to fail with an error response
Environment
Running locally on a Mac
- Clair version/image: git tag
v4.7.2
- Clair client name/version: curl
- Host OS: MacOS
- Kernel (e.g.
uname -a
): - Kubernetes version (use
kubectl version
): n/a - Network/Firewall setup: n/a
Reading up with the help of https://dev.to/mokiat/proper-http-shutdown-in-go-3fji
I think the current behaviour is due to srvs.Wait() returning as soon as the servers are Shutdown()
(stop accepting requests), which runs off the end of main.go and the process exits, even though other goroutines are still running. For example unregistered signal handler never gets logged
draft PR #1951 improves this a bit, but I can't get in-flight requests to continue processing for a grace period. Details in the draft PR
I took a whack at this in #1954, but I think it will require go1.21 API to work correctly.