Open dany74q opened 3 days ago
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
RegisterOnShutdown
is documented as: "This can be used to gracefully shutdown connections that have undergone ALPN protocol upgrade or that have been hijacked.". If there's no more connections and the shutdown proceeds, then there's nothing for the hook to do anyway.
Also, please include proposed API changes in your proposal.
Thanks Sean !
Valid point about the hooks - I thought it might make sense for Shutdown() to wait on all hooks to finish before returning, just in-case the caller set-up hooks which outlive the server itself; the doc is formulated well though, so this is probably a moot point.
I've edited the original message to be more concrete on the proposals.
Proposal Details
Currently, when gracefully terminating an http1 server using
http.Server#Shutdown()
, it will:I'd like to hear the community's thoughts about minor changes to the points above, which I believe could help implement a safer graceful termination flow:
1. User-supplied hooks
Would it make more sense to wait for the hooks before exiting
Shutdown()
? otherwise we don't guarantee the hooks will execute beforeShutdown()
is finished, and potentially the process is terminated.Proposal
http.Server#Shutdown()
2. Hard-coded 5 seconds for treating active connections as idle
The code mentions:
Proposal
ReadHeaderTimeout
and fall-back to the default of 5 seconds if it isn't set3. Closing idle connections
For http1, when connections are reused, they are marked as idle as soon as a response is served; this means that reused connections can toggle rapidly between active / idle when serving requests, and get shutdown if caught idle in the loop above.
I think we should take a small nuance into account for graceful termination - a client might just be before re-using an idle connection, while the server closes it, leading to an EOF on the client side; for non idempotent requests (say, POST), this wouldn't be retried automatically by clients - the request is usually dropped, even if there's a new server already accepting requests (say, a version roll of a server, gracefully terminating the former).
This is the nature of http1, of course. I would like to propose a minor change that would help servers better control this scenario, as I've found, could appear in critical applications (e.g. security-enforcing k8s admission controllers)
Proposal
Allow controlling the window of - when an idle connection is treated as idle - by introducing a
time.Duration
, where only connections that had been idle for at least that long will be closed (similar toIdleTimeout
, but for closing)http.Server
-CloseIdleMinDuration
closeIdleConns
, get the connection state change time fromconn#getState
CloseIdleMinDuration
had passed since the state's unixSecWith this, the server can configure that, say, it would only close connections that were idle for 30 seconds - increasing the odds that the connection is truly idle, and is not about to be active in a brief moment.
This has similar, but different semantics to
IdleTimeout
, which would close connections at runtime - as it would only scope it to the termination period; this could make more sense for http1, as we can never fully guarantee a connection is not just about to be re-used.Appreciate your Time !
golang-nuts discussion: https://groups.google.com/g/golang-nuts/c/G6Ct8kzZiRU