feat(http1): graceful shutdown first byte timeout #3808
+295
−39
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This commit introduces a new
Connection::graceful_shutdown_with_config
method that gives users control over the HTTP/1 graceful process.Before this commit, if a graceful shutdown was initiated on an inactive connection hyper would immediately close it.
As of this commit the
GracefulShutdownConfig::first_byte_read_timeout
method can be used to give inactive connections a grace period where, should the server begin receiving bytes from them before the deadline, the request will be processed.HTTP/2 Graceful Shutdowns
This commit does not modify hyper's HTTP/2 graceful shutdown process.
hyper
already uses the HTTP/2GOAWAY
frame, meaning thathyper
already gives inactive connections a brief period during which they can transmit their final requests.Note that while this commit enables slightly more graceful shutdowns for HTTP/1 servers, HTTP/2 graceful shutdowns are still superior.
HTTP/2's
GOAWAY
frame allows the server to finish processing a last batch of multiple incoming requests from the client, whereas the new graceful shutdown configuration in this commit only allows the server to wait for one final incoming request to be received.This limitations stems from a limitation in HTTP/1, where there is nothing like the
GOAWAY
frame that can be used to coordinate the graceful shutdown process with the client in the face of multiple concurrent incoming requests.Instead for HTTP/1 connections
hyper
gracefully shuts down by disabling Keep-Alive, at which point the server will only receive at most one new request, even if the client has multiple requests that are moments from reaching the server.Motivating Use Case
I'm working on a server that is being designed to handle a large amount of traffic from a large number of clients.
It is expected that many clients will open many TCP connections with the server every second.
As a server receives more traffic it becomes increasingly likely that at the point that it begins gracefully shutting down there are connections that were just opened, but the client's bytes have not yet been seen by the server.
Before this commit, calling
Connection::graceful_shutdown
on such a freshly opened HTTP/1 connection will immediately close it. This means that the client will get an error, despite the server having been perfectly capable of handling a final request before closing the connection.This commit solves this problem for HTTP/1 clients that tend to send one request at a time.
By setting a
GracefulShutdownConfig::first_byte_read_timeout
of, say, 1 second, the server will wait a moment to see if any of the client's bytes have been received.During this period, the client will have been informed that Keep-Alive is now disabled, meaning that at most one more request will be processed.
Clients that have multiple in-flight requests that have not yet reached the server will have at most one of those requests handled, even if all of them reach the server before the
first_byte_read_timeout
. This is a limitation of HTTP/1.Work to do in other Crates
hyper-util
To expose this to users that use
hyper-util
, a method should be added tohyper-util
'sConnection
type.This new
hyper-util Connection::graceful_shutdown_with_config
method would expose ahttp1_first_byte_read_timeout
method that would leadhyper-util
to sethyper GracefulShutdownConfig::first_byte_read_timeout
.Closes #3792