Skip to content

Fix TokenBucketRateLimiter AttemptAcquire(0) with fractional tokens#124498

Open
apoorvdarshan wants to merge 1 commit intodotnet:mainfrom
apoorvdarshan:fix/token-bucket-fractional-tokencount
Open

Fix TokenBucketRateLimiter AttemptAcquire(0) with fractional tokens#124498
apoorvdarshan wants to merge 1 commit intodotnet:mainfrom
apoorvdarshan:fix/token-bucket-fractional-tokencount

Conversation

@apoorvdarshan
Copy link

Summary

  • Fix AttemptAcquire(0) incorrectly succeeding when _tokenCount holds a fractional value (e.g. 0.5) by changing three availability checks from > 0 / != 0 to >= 1
  • This makes the "probe" behavior of AttemptAcquire(0) consistent with GetStatistics().CurrentAvailablePermits, which truncates to (long) and reports 0
  • Add a regression test that verifies fractional tokens are not treated as available permits

Fixes #118192

Test plan

  • Verify new test AttemptAcquireZeroWithFractionalTokensReportsUnavailable passes
  • Verify all existing TokenBucketRateLimiterTests continue to pass
  • dotnet test src/libraries/System.Threading.RateLimiting/tests/System.Threading.RateLimiting.Tests.csproj

🤖 Generated with Claude Code

…al _tokenCount

Change availability checks from > 0 / != 0 to >= 1 so fractional tokens
below 1.0 are not treated as available permits, making AttemptAcquire(0)
consistent with GetStatistics().CurrentAvailablePermits.

Fixes dotnet#118192
Copilot AI review requested due to automatic review settings February 17, 2026 07:09
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Feb 17, 2026
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug in TokenBucketRateLimiter where AttemptAcquire(0) incorrectly succeeded when fractional tokens were present (e.g., _tokenCount = 0.5). The issue arose because _tokenCount is stored as a double for accurate replenishment calculations, but availability checks used > 0 or != 0 instead of >= 1, causing inconsistency with GetStatistics().CurrentAvailablePermits which truncates to long.

Changes:

  • Changed three availability checks from > 0 / != 0 to >= 1 to ensure fractional tokens are not treated as available permits
  • Added regression test AttemptAcquireZeroWithFractionalTokensReportsUnavailable that verifies the probe behavior with fractional tokens

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/TokenBucketRateLimiter.cs Fixed three conditions in AttemptAcquireCore, AcquireAsyncCore, and TryLeaseUnsynchronized to check _tokenCount >= 1 instead of > 0 or != 0
src/libraries/System.Threading.RateLimiting/tests/TokenBucketRateLimiterTests.cs Added regression test that drains tokens, replenishes to create fractional tokens (~0.5), and verifies AttemptAcquire(0) correctly returns unavailable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-System.Threading community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TokenBucketRateLimiter: AttemptAcquire(0) succeeds while CurrentAvailablePermits is 0 due to fractional _tokenCount

1 participant