Allow connection pools to stop reusing an HTTP/2 connection before its keep-alive timeout
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- rust
調査の方向性
まず、提案で説明されている HTTP/2 クライアントビルダーと hyper::client::conn::http2 API から始め、既存の keep-alive PING タイムアウトと Timer 抽象化を追跡してください。hyper-util legacy Client が KeepAliveObserver と接続ごとの PoisonPill をどのように利用するかを確認してください。完了の条件は、IO を閉じたり、ストリームをキャンセルしたり、直接の SendRequest の readiness を変更したりせずに、オプションの通知 API が公開されていることです。
索引モデルが issue の本文から書いたものです。
説明
Is your feature request related to a problem? Please describe.
An HTTP/2 connection can remain locally ready while its network path is unavailable. If no earlier transport or protocol error is observed, a connection pool can keep assigning new requests to that connection until the keep-alive PING timeout closes it.
A concrete scenario is a network failover or NAT/firewall state change after which new connections succeed but an existing connection remains unusable. The replacement path may have lost the old connection's state: a new TCP handshake can establish fresh state, while packets belonging to the old connection are silently dropped. If the client receives no FIN, RST, or other definitive error, the existing H2 connection can remain eligible for reuse locally even though it cannot make progress. Continuing to assign requests to it delays recovery despite a working path for new connections.
There are documented examples of the underlying network behavior:
- Google Cloud NAT documents that removing an external NAT IP without first draining it deletes the associated connection-tracking entries and drops all return traffic. With another usable NAT IP available, this provides a scenario where fresh connections can work while the old mapping no longer carries responses.
This does not assume that every network failover invalidates existing connections. A temporary interruption may also recover, which is why stopping reuse should not itself terminate existing streams.
There are two different policies involved: how long to keep existing streams alive during a recoverable interruption, and how long to keep assigning new work to that connection. Reducing the keep-alive timeout improves replacement latency, but also terminates existing streams earlier.
For example, an application may want to retain a 60-second PING timeout for existing streams while stopping reuse after an outstanding keep-alive PING has waited 5 seconds for an ACK. These are example settings, not proposed defaults.
Describe the solution you'd like
Would an optional reuse-timeout notification on the HTTP/2 client builder fit Hyper's API?
The proposal adds keep_alive_reuse_timeout(Option<Duration>) and a per-connection KeepAliveObserver. The observer would be exposed through hyper::client::conn::http2. A pool such as hyper-util's legacy Client could use the notification to retire its own connection entry.
- The option defaults to disabled.
- Its timer starts with the existing keep-alive PING timeout phase.
- An ACK ready before notification cancels the soft wait.
- On expiry, Hyper invokes a nonblocking observer once, outside the PING state lock.
- The original hard deadline continues to run. Notification does not close IO, send GOAWAY, cancel streams, or change direct
SendRequestreadiness. - A late ACK does not generate a reversal notification; the consuming pool owns its retirement policy.
The implementation uses Hyper's Timer abstraction and does not require changes to h2 or its dependency constraints.
Describe alternatives you've considered
Shortening the hard timeout also reduces interruption tolerance for existing streams. Application-level health requests or rebuilding an entire Client can provide a separate signal, but add another probe and broader connection-management logic. Deriving the signal from the existing PING wait keeps it specific to one connection.
Additional context
This issue tracks both parts of the proposal, with one implementation PR per repository:
- Hyper: expose the optional PING reuse-timeout notification through the HTTP/2 client API.
- hyper-util: add
http2_keep_alive_reuse_timeout(Option<Duration>)to the legacy Client builder and bind each H2 handshake to an observer holding only that connection'sPoisonPill. Existing pool checks then retire the entry without canceling its active streams.
The hyper-util setting would default to disabled. Its retirement policy would be irreversible even after a late ACK. Requests already checked out can race with retirement; neither PR migrates or replays requests or establishes connections proactively.
The hyper-util PR depends on the Hyper API. It can be reviewed as a draft using a companion checkout for validation, but must use an actual released Hyper version containing the API before it is ready to merge. Neither PR needs an h2 version pin.
- 主要言語
- Rust
- スター
- 16.3k
- フォーク
- 1.8k
- 平均マージ
- 1日 23時間
- マージ済み PR(30日)
- 13
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
hyperium/hyper のほかの issue
-
C-feature
難易度 1/5 1時間未満 初心者へのやさしさ 65/100
-
C-bug S-waiting-on-author
-
A-http2 C-bug
-
C-bug
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
-
A-client C-bug E-pr-welcome K-hyper-util
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
TheLarkInn/aipm#2413 ·
-
documentation
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
alexgorbatchev/simple-ptt#15 ·
-
tooling
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
todo:ticket
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
taikoxyz/taiko-mono#22168 · コメント 1 件 ·