fix(sse): saturate exponential reconnect backoff to avoid overflow panic - #1231
fix(sse): saturate exponential reconnect backoff to avoid overflow panic#1231ump45nose wants to merge 2 commits into
Conversation
ExponentialBackoff::retry computed the reconnect multiplier with 2u32.pow(current_times). With max_times unset, current_times can reach the bit width, panicking in debug builds and wrapping to a zero delay in release builds for long-lived SSE clients. Use saturating_pow and Duration::saturating_mul so the delay stays monotonic and panic-free.
| let multiplier = 2u32.saturating_pow(current_times as u32); | ||
| Some(self.base_duration.saturating_mul(multiplier)) |
There was a problem hiding this comment.
Once the multiplier reaches its limit, the delay can be decades long. The caller passes it directly to tokio::time::sleep, so the stream neither reconnects nor terminates.
Saturating the multiplier alone can still yield decades-long sleeps once current_times reaches the bit width, pinning the stream in tokio::time::sleep without reconnecting or terminating. Add an optional max_delay (default 30s) that clamps the computed delay, keeping the backoff monotonic and panic-free while guaranteeing the client retries.
|
Thanks for the catch — you're right that a saturating multiplier alone leaves the delay unbounded, and at the saturated value Pushed a follow-up that adds an optional Added a regression test (
|
Summary
fix(sse): saturate exponential reconnect backoff to avoid overflow panic
Verification
cargo test -p rmcp --features client-side-sse --lib client_side_sse (16 passed); cargo clippy -p rmcp --features client-side-sse --lib (no new warnings); cargo fmt --check (clean)
Related to #1198