RequestProgressBroker::publish holds its RwLock read guard across sender.send().await (request_progress.rs:84-93). The two brokers in tool_event_broker.rs handle the same situation by cloning the sender and dropping the guard before awaiting; this one does not.
The broker is process-global, which is what makes this worse than a per-request stall. A single blocked send (see #229 for the reproduced blocking condition on a sibling channel) pins the read guard indefinitely. Every subscribe and unsubscribe on the write side queues behind it, so unrelated requests stop being able to register or clean up progress channels. Verified against main 2026-07-17. Not reproduced live, since that needs 1024+ progress notifications against a wedged consumer.
RequestProgressBroker::publish holds its RwLock read guard across sender.send().await (request_progress.rs:84-93). The two brokers in tool_event_broker.rs handle the same situation by cloning the sender and dropping the guard before awaiting; this one does not.
The broker is process-global, which is what makes this worse than a per-request stall. A single blocked send (see #229 for the reproduced blocking condition on a sibling channel) pins the read guard indefinitely. Every subscribe and unsubscribe on the write side queues behind it, so unrelated requests stop being able to register or clean up progress channels. Verified against main 2026-07-17. Not reproduced live, since that needs 1024+ progress notifications against a wedged consumer.