ProgressDispatcher: a slow progress subscriber blocks subscribe() and delivery for other tokens
メンテナーはふだん 3 日以内に返信
評価
調査の方向性
Start in crates/rmcp/src/handler/client/progress.rs and review PR #1310, which contains the proposed fix and tests. Run test_slow_subscriber_does_not_block_other_tokens, test_resubscribing_a_dropped_token_keeps_the_new_subscriber, test_dropping_a_replaced_subscriber_keeps_its_replacement, and dropping_a_subscriber_unregisters_it_without_a_runtime; done means all pass without changing the public API.
索引モデルが issue の本文から書いたものです。
説明
Describe the bug
ProgressDispatcher::handle_notification (crates/rmcp/src/handler/client/progress.rs) holds the read guard of its tokio::sync::RwLock across sender.send(notification).await. When one subscriber's channel is full (capacity 16), that send waits while the guard is held. Tokio's RwLock is write-preferring, so a concurrent subscribe() then waits for the write lock, and every later notification for other tokens queues behind it. One slow consumer stalls progress notifications for all in-flight requests until it catches up or is dropped.
Two smaller problems in the same file:
ProgressSubscriber::dropremoves its entry withtokio::spawn, so dropping a subscriber outside a Tokio runtime panics (there is no reactor running).- Because that removal is deferred, dropping a subscriber and subscribing again with the same token can remove the new subscription, and the new stream then receives no notifications.
To Reproduce
PR #1310 adds tests for all three: test_slow_subscriber_does_not_block_other_tokens, test_resubscribing_a_dropped_token_keeps_the_new_subscriber, test_dropping_a_replaced_subscriber_keeps_its_replacement and the unit test dropping_a_subscriber_unregisters_it_without_a_runtime. By the PR's own runs they fail on main and pass with the change.
Expected behavior
A slow subscriber only delays its own token, and dropping or replacing a subscriber never affects another subscription.
Additional context
The fix in #1310 holds a std::sync::RwLock only to look up, insert or remove an entry and releases it before sending; Drop removes only its own entry, synchronously. The public API does not change. If you would rather keep the async lock and only shorten the critical section, I can rework it that way.
Disclosure: an AI agent (Claude, via Claude Code) that I run found the problem, wrote the fix and tests in #1310, and wrote and posted this issue.
- 主要言語
- Rust
- スター
- 4k
- フォーク
- 654
- 平均マージ
- 4日 3時間
- マージ済み PR(30日)
- 40
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
modelcontextprotocol/rust-sdk のほかの issue
-
P3 question T-documentation T-enhancement
難易度 1/5 1時間未満 初心者へのやさしさ 86/100
modelcontextprotocol/rust-sdk#1155 ·
メンテナーはふだん 3 日以内に返信
-
LocalSessionManager session workers don't cancel in-flight tool calls on client disconnect (follow-up to #857)対応中かも @kkkhs が 1 日前に担当しました。 オープンbug P1 ready for work T-transport
難易度 4/5 3〜5日 初心者へのやさしさ 55/100
modelcontextprotocol/rust-sdk#1325 ·
メンテナーはふだん 3 日以内に返信
-
streamable-http server: client responses to server-initiated requests (sampling/elicitation/roots) are 202-accepted and silently discarded under the 2026-07-28 protocol — the pending request hangs forever対応中かも @DaleSeo が 2 日前に担当しました。 オープンbug P1 ready for work T-transport
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
modelcontextprotocol/rust-sdk#1321 · リアクション 1 件 · 担当者 1 名 ·
メンテナーはふだん 3 日以内に返信
-
Bound pre-lifecycle bootstrap attempts in server initialization対応中かも @DaleSeo が 6 日前に担当しました。 オープンenhancement P2 T-service T-transport
modelcontextprotocol/rust-sdk#1315 · 担当者 1 名 ·
メンテナーはふだん 3 日以内に返信
-
transport::stdio() runs every read and write on tokio's blocking pool, which caps stdio throughput対応中かも @itsmunzir が 11 日前に担当しました。 オープンenhancement P2 T-transport
難易度 4/5 3〜5日 初心者へのやさしさ 58/100
modelcontextprotocol/rust-sdk#1301 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
modelcontextprotocol/rust-sdk の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
antithesishq/bombadil#361 ·
メンテナーはふだん 1 日以内に返信
-
test(executor_l0): assert execute() TaskOutcome, not only bus events / 断言 execute() 返回的 TaskOutcomeオープンtype:debt
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
skaiy/wild_agentos#425 ·
メンテナーはふだん 1 日以内に返信
-
Default-import note suggests `import * as process` for velt:process, which does not name the builtinオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
bug ticket
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
cratestack/cratestack#1154 ·
メンテナーはふだん 1 日以内に返信
-
status:needs-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信