-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TokenBucketRateLimiter.WaitAsync() does not immediately reduce the _queueCount on cancellation #64078
Comments
Tagging subscribers to this area: @mangod9 Issue DetailsDescription
Reproduction Stepsvar limiter = new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1,
TimeSpan.Zero, 1, autoReplenishment: false));
limiter.Acquire(1);
var cts = new CancellationTokenSource();
var firstWaitTask = limiter.WaitAsync(1, cts.Token);
cts.Cancel();
await Assert.ThrowsAsync<OperationCanceledException>(() => firstWaitTask.AsTask());
// This incorrectly returns a failed lease immediately because ctc.Cancel() did not reduce the _queueCount.
var secondWaitTask = limiter.WaitAsync(1, cts.Token);
//Assert.False(secondWaitTask.IsCompleted)
Assert.True(limiter.TryReplenish());
// WaitAsync() no longer returns a failed lease because we called TryReplenish(), but that shouldn't be necessary
var thirdWaitTask = limiter.WaitAsync(1, cts.Token);
Assert.False(thirdWaitTask.IsCompleted) Expected behaviorThe Actual behaviorThe Regression?No. Known WorkaroundsNo response ConfigurationNo response Other informationNo response
|
Sounds similar to #761. They're using the same helper type, right? We might want to address them together. I haven't fixed that one yet as I've been concerned about the perf impact. |
I'm not very familiar with the Channel code. What helper type are you referring to? AsyncOperation? I don't think were sharing anything. I think the following code will need to be changed to decrement Lines 132 to 135 in 0b8204f
And this logic will need to be updated to not decrement Lines 277 to 286 in 0b8204f
We're also somewhat concerned about perf because the |
Ah, ok. I must be misremembering. I thought it was also using AsyncOperation, but I must have been thinking of this: Line 311 in 67848f2
|
Description
TokenBucketRateLimiter.WaitAsync(int, CancellationToken)
still counts the requested tokens against theQueueLimit
after they've been canceled by theCancellationToken
after an incompleteValueTask
is returned. This is eventually fixed when the request is dequeued from theDeque<RequestRegistration>
byReplenishInternal
, but that could be too late.Reproduction Steps
Expected behavior
The
secondWaitTask
should initially be incomplete and later complete successfully when theTokenBucketRateLimiter
is replenished.Actual behavior
The
secondWaitTask
immediately returns a non-acquired lease because theQueueLimit
has supposedly been exceeded (but not really).Regression?
No.
Known Workarounds
No response
Configuration
No response
Other information
No response
The text was updated successfully, but these errors were encountered: