Skip to content

Fix misleading zeroTime documentation in TokenBucket.h#2658

Open
UditDewan wants to merge 1 commit into
facebook:mainfrom
UditDewan:fix-tokenbucket-zerotime-doc
Open

Fix misleading zeroTime documentation in TokenBucket.h#2658
UditDewan wants to merge 1 commit into
facebook:mainfrom
UditDewan:fix-tokenbucket-zerotime-doc

Conversation

@UditDewan

Copy link
Copy Markdown

Summary

The constructors and reset() of TokenBucketStorage, BasicDynamicTokenBucket, and BasicTokenBucket document the default zeroTime = 0 as producing an empty bucket. The actual balance is min((time - zeroTime) * rate, burstSize), so the default of 0 (the clock epoch -- machine boot for steady_clock) yields a full bucket at all but very low rates, and a partially-filled one at very low rates.

This mismatch is the root cause of the confusion in #2430: a default-constructed DynamicTokenBucket at rate = 0.0001 was expected to hold one token (empty buckets that immediately served single-token consumes at normal rates reinforced that expectation), but it actually held uptime * rate tokens (~0.376 on the reporter's machine), so consumeWithBorrowNonBlocking correctly borrowed the remaining ~0.624 tokens and returned a wait of 0.624 / 0.0001 = 6241.23s -- exactly the value in the reported failure. There is no precision bug; the documentation was describing semantics the code never had.

This updates the five affected doc comments to state the real balance formula and how to start with an actually-empty bucket (pass the current time / defaultClockNow() as zeroTime).

Fixes #2430

Test plan

Documentation-only change; no code modified.

🤖 Generated with Claude Code

The constructors and reset() of TokenBucketStorage,
BasicDynamicTokenBucket, and BasicTokenBucket document the default
zeroTime = 0 as producing an empty bucket. The actual balance is
min((time - zeroTime) * rate, burstSize), so zeroTime = 0 (the clock
epoch) yields a *full* bucket at all but very low rates, and a
partially-filled one at very low rates.

This mismatch caused the confusion in facebook#2430, where a default-constructed
DynamicTokenBucket at rate 0.0001 was expected to hold one token but
held only uptime * rate tokens. Document the real semantics and how to
start with an actually-empty bucket.

Fixes facebook#2430

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@meta-cla meta-cla Bot added the CLA Signed label Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DynamicTokenBucket::consumeWithBorrowNonBlocking will return incorrect value with very low rate

1 participant