Open fabianfett opened 2 years ago
Hmm maybe this is why I was having issues performing a soft-restart of a HTTP/2 Vapor server. I remember seeing quiesce/shutdown errors.
- Once
NIOHTTP2Handler
receives aChannelShouldQuiesceEvent
a GoAway frame should be send to the client and new incoming streams should be rejected.- Once all previously open streams have finished the connection should be closed.
This needs to be handled carefully, the server should attempt to allow for 'in-flight' streams to be opened before it begins to reject streams. It can do this by sending a GOAWAY frame with lastStreamID
set to .max
followed immediately by a PING. On receiving the PING ACK – and thereby knowing the client received the previous GOAWAY frame – the server can send another GOAWAY frame with a lower lastStreamID
, and then begin rejecting streams.
The client may for some reason not send a PING ACK which could leave the server waiting indefinitely. As the library doesn't (currently) have a built-in mechanism to retrieve RTT the server should also set a timer as a fallback mechanism.
In gRPC Swift this is managed by a separate channel handler with a number of different behaviours, many of which are applicable to http servers in general. These include:
As these are generally useful it may make sense to fold these behaviours (along with the graceful shutdown) either into the NIOHTTP2Handler
or into a separate channel handler within swift-nio-http2
.
SwiftNIOExtras offers a
QuiescingHelper
to gracefully shutdown servers. NIOHTTP2Handler should support shutting down a server connection, when theQuiescingHelper
sends out aChannelShouldQuiesceEvent
:NIOHTTP2Handler
receives aChannelShouldQuiesceEvent
a GoAway frame should be send to the client and new incoming streams should be rejected.In
NIOHTTP1
theChannelShouldQuiesceEvent
support is implemented inHTTPServerPipelineHandler