Skip to content

feat(http2): add an optional keep-alive reuse timeout observer - #4187

Open
jiahaoliang wants to merge 4 commits into
hyperium:masterfrom
jiahaoliang:pr/h2-keepalive-reuse-timeout
Open

feat(http2): add an optional keep-alive reuse timeout observer#4187
jiahaoliang wants to merge 4 commits into
hyperium:masterfrom
jiahaoliang:pr/h2-keepalive-reuse-timeout

Conversation

@jiahaoliang

Copy link
Copy Markdown

fix: #4186

Connection pools may need to stop assigning new requests to an unresponsive H2 connection while retaining a longer keep-alive timeout for its existing streams. This PR implements the Hyper portion of the shared reuse-timeout proposal: a connection-specific notification for that policy without shortening the existing hard timeout. The companion hyper-util PR handles pool retirement.

The HTTP/2 client builder gains keep_alive_reuse_timeout(Option<Duration>) and keep_alive_observer(...), with KeepAliveObserver exposed under hyper::client::conn::http2.

The new timeout defaults to disabled. When enabled, an independent timer follows the existing keep-alive PING timeout phase. If the ACK is still pending when that timer expires, the observer is taken and invoked once after releasing the PING state lock. The original hard timer remains registered with its original deadline.

Behavioral details:

  • ACK processing precedes timeout notification when an ACK is ready in the same poll.
  • If both deadlines have already expired without a ready ACK, the existing hard-timeout path takes priority.
  • Notification does not close IO, send GOAWAY/RST_STREAM, cancel streams, change request readiness, or replay requests.
  • Standalone adaptive-window PINGs do not start a separate reuse timeout.
  • A configured reuse timeout must be nonzero and less than the hard timeout when keep-alive is enabled. Handshake validates the final builder configuration, independent of setter order.
  • No server-facing policy or runtime dependency is added. Cargo.toml, including the existing h2 version range, is unchanged.

Validation covers timer wakeup without IO, preservation of the hard deadline, one-shot observer consumption, and configuration boundaries. Companion hyper-util tests exercise pool retirement and completion of existing response headers and streaming bodies over paused duplex IO. Review CI passed 124 Hyper unit tests, the client/server feature checks, and documentation and formatting checks. The dependency resolver selected h2 0.4.19 with the unchanged upstream version range.

This is intended as a narrow notification API; the connection pool owns retirement and replacement. API naming and placement are open to maintainer feedback.

Notify connection pools without shortening the hard timeout for active streams.
Keep the existing h2 dependency range and expose the observer on the H2 client API.
Cover timer wakeups and final-configuration validation.
@jiahaoliang

Copy link
Copy Markdown
Author

Use my own word to summary:
I think the code itself and the LLM report already covers what it does. Just add a KeepAliveObserver trait that triggers whenever a per-connection reuse timeout reached. In hyper-util hyperium/hyper-util#319 , I implement KeepAliveObserver as poisoning the underlying connection in the client connection pool.

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.

Allow connection pools to stop reusing an HTTP/2 connection before its keep-alive timeout

1 participant