keepalive timer also closes a freshly dialed pooled connection during the HTTP/1.1 TLS upgrade
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 58/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- erlang
- 領域
- backend, networking
調査の方向性
Start with the fresh-dial path in hackney_pool.erl:573-587 and 1005-1024, then trace connected and upgrade_to_ssl in hackney_conn.erl:845-869 and 996-1013. Compare the HTTP/1.1 and HTTP/2 upgrade branches, and run the pool-enabled HTTP/1 TLS-upgrade tests with a delayed handshake; done means a fresh connection is not closed by the keepalive timer during that handshake.
索引モデルが issue の本文から書いたものです。
説明
hackney 4.7.4 (also current master).
#934 disarms the keepalive timer in the is_ready probe, which covers a reused pooled connection. A fresh dial does not reach is_ready:
handle_call({checkout, ...})takes thenone -> start_connectionbranch (hackney_pool.erl:573-587).- The new conn arms
idle_timeout = keepalive_timeouton entry toconnected(hackney_conn.erl:845-869).keepalive_timeoutis capped at 2000 ms bymin/2inhackney_pool.erl:476-482(aninfinityvalue also collapses to 2000 because of Erlang term order), andstart_connection/6does not take a per-checkout override (hackney_pool.erl:1005-1024). - The HTTP/1.1 branch of
upgrade_to_sslreturnskeep_stateand leaves thatstate_timeoutrunning (hackney_conn.erl:1012-1013). The HTTP/2 branch cancels it viainit_h2_after_upgrade(:2995-3007). ssl:connect/3at:996blocks the gen_statem. If the TLS handshake takes longer than the remaining timer, the timer fires (:915-917), the conn goes toclosed, and the caller's{request, ...}hits the catch-all and gets{error, invalid_state}(:2005-2006on 4.7.4;{error, closed}on master after #936). No byte of the request has been written at that point.
Reproduced with a TCP proxy in front of api.stripe.com that delays the ClientHello: a 1900 ms delay succeeds, a 2200 ms delay fails with invalid_state, with pool enabled and protocols: [http1]. With prewarm_count: 0 the fresh-dial path is the only path, so the failure rate is simply the fraction of handshakes slower than ~2 s.
Suggested fix: arm the idle timer in connected(enter) only when owner =:= pool_pid (prewarm conns set owner => PoolPid at hackney_pool.erl:1367; fresh-dial conns set owner => Requester at :1024), cancel it in set_owner when the new owner is not the pool, and add the HTTP/2 branch's CancelIdle action to the HTTP/1.1 branch of upgrade_to_ssl.
Related: #916 (stuck in upgrade_to_ssl), #922 (handshake bounded by connect_timeout), #934, #936.
- 主要言語
- Erlang
- スター
- 1.4k
- フォーク
- 458
- 平均マージ
- 11時間 32分
- マージ済み PR(30日)
- 47
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
benoitc/hackney のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 48/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
benoitc/hackney#907 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
feature
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
benoitc/hackney#596 · コメント 4 件 ·
メンテナーはふだん 1 日以内に返信
benoitc/hackney の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
Natvs/Nt.Automaton#33 ·
-
enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
volcano-sh/volcano#6322 ·
メンテナーはふだん 1 日以内に返信
-
claude
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
sprain/sprainocchio#38 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
peach-mitao/peach#693 ·
メンテナーはふだん 1 日以内に返信