Skip to content

feat(server): add Connection::shutdown_notice - #1001

Open
derekargueta wants to merge 1 commit into
hyperium:masterfrom
derekargueta:shutdown-notice
Open

derekargueta wants to merge 1 commit into
hyperium:masterfrom
derekargueta:shutdown-notice

Conversation

@derekargueta

Copy link
Copy Markdown

graceful_shutdown sends both GOAWAYs that RFC 9113 §6.8 describes:

  1. the first, with the last stream ID set to 2^31-1;
  2. a PING;
  3. the final GOAWAY, as soon as the PING is acknowledged.

A server therefore can't warn clients that a shutdown is coming and finish it later. That split is what proxies do when they drain. For example, Envoy sends the first GOAWAY as soon as a connection starts draining. Clients can then move new requests elsewhere, while requests already in flight are still accepted. Envoy sends the final GOAWAY only once its drain_timeout has passed.

This PR adds server::Connection::shutdown_notice(), which:

  • sends the first GOAWAY (last stream ID 2^31-1, NO_ERROR) and the shutdown PING;
  • does not send the final GOAWAY. That waits for a later graceful_shutdown(), which sends it:
    • at once if the PING has already been acknowledged, because the client has seen the notice;
    • otherwise, when the acknowledgement arrives, as graceful_shutdown does today;
  • keeps accepting new streams;
  • keeps an idle connection open until graceful_shutdown() is called;
  • does nothing if a GOAWAY has already been sent.

When shutdown_notice isn't used, graceful_shutdown behaves exactly as before.

Implementation: GoAway tracks whether the notice is Sent or Acked. While a notice is outstanding, the shutdown PING's acknowledgement records that the client has seen it instead of sending the final GOAWAY.

Tests: two new tests in tests/h2-tests/tests/server.rs:

  • shutdown_notice_then_graceful_shutdown: the notice and its PING are sent, and the connection keeps taking streams after the acknowledgement. Then graceful_shutdown sends GOAWAY(3) without a second PING.
  • graceful_shutdown_before_shutdown_notice_acked: repeated shutdown_notice and graceful_shutdown calls send one GOAWAY and one PING. The final GOAWAY follows the acknowledgement, and a stream that was in flight still completes.

Related: hyperium/hyper#3961 (a different shutdown sequence, with the same goal of telling clients early).

🤖 Generated with Claude Code

Sends the first GOAWAY of a graceful shutdown (last stream ID 2^31-1)
and a PING, without the final GOAWAY, which waits for
`graceful_shutdown`. If the PING was acknowledged by then, the final
GOAWAY goes at once; otherwise it goes when the acknowledgement comes,
as before.

This lets servers warn clients of a shutdown when they start draining
and finish it later, as Envoy does with `drain_timeout`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant