fix: guard resubscribeDelay against inputs that would panic - #154
Conversation
resubscribeDelay(attempt) shifts by attempt-1, so any attempt below 1 shifts by a negative amount, which is a runtime panic rather than a bad return value: resubscribeDelay(0) -> runtime error: negative shift amount rand.Int63n has the same shape: it panics on a non-positive argument, so setting resubscribeBaseDelay to 0 to disable jitter would panic instead of degrading to no delay. Neither is reachable today. The only callers pass a literal 1 or are guarded by `attempt > 0`, but that guard sits in startPersistentSubscription, a different function from the arithmetic it protects, so a new caller or a refactor that moves the check reintroduces it silently. Worth guarding rather than documenting because of the blast radius. An unrecovered panic in a goroutine takes down the process, and every subscription reconnects at once when it comes back - the synchronised burst this backoff exists to prevent. Both bounds now belong to the function that needs them. Added a test that fails with "negative shift amount" without the clamp. Claude-Session: https://claude.ai/code/session_01NzMsjNwuQU9gwwcbUvpL5G
|
Warning Review limit reached
Next review available in: 46 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Follow-up to #153, from reviewing it after merge.
The problem
resubscribeDelay(attempt)shifts byattempt-1, so anyattemptbelow 1 shifts by a negative amount — which is a runtime panic, not a bad return value:rand.Int63nhas the same shape: it panics on a non-positive argument, so settingresubscribeBaseDelay = 0to disable jitter would panic rather than degrade to no delay.Why guard it rather than document it
Neither is reachable today — the only callers pass a literal
1, or are guarded byattempt > 0. But that guard lives instartPersistentSubscription, a different function from the arithmetic it protects. A new caller, or a refactor that moves the check, reintroduces it silently.The blast radius is what makes it worth a clamp. An unrecovered panic in a goroutine takes down the whole process. http-nostr runs a single replica, so every subscription drops at once and reconnects together when it restarts — the synchronised burst #153 exists to prevent. A one-line arithmetic slip would undo the fix it lives inside.
Both bounds now belong to the function that needs them.
Test
TestResubscribeDelayHandlesAttemptsBelowOnecovers0,-1,-1000. Verified it's a real regression test, not a vacuous one — with the clamp removed:and it passes with the clamp restored. Full suite green,
gofmt/go build/go vetclean.Deploy note
Worth landing before the deployment pin is moved off the branch build, so production goes from
fix-stagger-resubscribe-5d15f56to amain-tag once rather than twice.