You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
HTTP/2 server: announce a graceful shutdown without starting it #4259
http2::Connection::graceful_shutdown sends the first GOAWAY (with stream ID 2^31-1) and then the final GOAWAY one round trip later. Proxies that drain connections want to send the first GOAWAY when draining starts, keep serving the requests that were already in flight, and send the final GOAWAY later. Envoy, for example, waits until its drain_timeout has passed. hyper can't do this today.
I've proposed server::Connection::shutdown_notice() in h2 (hyperium/h2#1001). On top of it, hyper would add http2::Connection::shutdown_notice(self: Pin<&mut Self>), and hyper-util would add a matching method to the auto connections. Is this something you'd take? I have a branch ready.
Proxies that drain connections want to send the first GOAWAY when draining starts, keep serving the requests that were already in flight, and send the final GOAWAY later.
That's basically what hyper does already. The difference is it sends a the second GOAWAY earlier, but it will continue to allow you serve the accepted requests. It won't tear down the connection until all the handles have been dropped.
The spec suggests this as a way to handle graceful shutdown:
Activity on streams numbered lower than or equal to the last stream identifier might still complete successfully. The sender of a GOAWAY frame might gracefully shut down a connection by sending a GOAWAY frame, maintaining the connection in an "open" state until all in-progress streams complete.
If a different implementation is killing the connection immediately upon seeing the GOAWAY of NO_ERROR, that seems wrong.
Yeah sorry I worded that badly. You're right that in-flight requests are fine.
What I actually mean is new streams. After the first GOAWAY hyper only accepts new streams for about an RTT, then the final GOAWAY goes out and anything opened after that gets refused. I'd like to keep accepting new streams for longer and send the final GOAWAY when I decide to.
The use case is basically #3961: we're behind an LB, and on deploy there's a window between "you're being drained" and the LB actually sending traffic elsewhere. Envoy handles this with drain_timeout (first GOAWAY at drain start, final one when the timeout fires). With hyper, clients that keep opening streams during that window get refused and have to retry.
Not a correctness issue since those streams are retryable, more about avoiding a bunch of retries on every deploy. If you don't think it's worth new API I get it. If you're open to it, hyperium/h2#1001 adds shutdown_notice() on the h2 side, and the hyper part would just expose that on http2::Connection.
Activity
seanmonstar commentedon Nov 6, 2026
That's basically what hyper does already. The difference is it sends a the second GOAWAY earlier, but it will continue to allow you serve the accepted requests. It won't tear down the connection until all the handles have been dropped.
The spec suggests this as a way to handle graceful shutdown:
If a different implementation is killing the connection immediately upon seeing the GOAWAY of NO_ERROR, that seems wrong.
Or is there something else involved?
derekargueta commentedon Nov 6, 2026
Yeah sorry I worded that badly. You're right that in-flight requests are fine.
What I actually mean is new streams. After the first GOAWAY hyper only accepts new streams for about an RTT, then the final GOAWAY goes out and anything opened after that gets refused. I'd like to keep accepting new streams for longer and send the final GOAWAY when I decide to.
The use case is basically #3961: we're behind an LB, and on deploy there's a window between "you're being drained" and the LB actually sending traffic elsewhere. Envoy handles this with drain_timeout (first GOAWAY at drain start, final one when the timeout fires). With hyper, clients that keep opening streams during that window get refused and have to retry.
Not a correctness issue since those streams are retryable, more about avoiding a bunch of retries on every deploy. If you don't think it's worth new API I get it. If you're open to it, hyperium/h2#1001 adds
shutdown_notice()on the h2 side, and the hyper part would just expose that onhttp2::Connection.