Skip to content
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

Update RateLimiter queues on cancellation #64825

Merged
merged 3 commits into from
Feb 10, 2022

Conversation

BrennanConroy
Copy link
Member

Fixes #64078

Realized the issue wasn't specific to TokenBucket so updated the base test class.
Also, avoiding the extra allocations for a closure by implementing a custom TCS.

@ghost
Copy link

ghost commented Feb 4, 2022

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

Issue Details

Fixes #64078

Realized the issue wasn't specific to TokenBucket so updated the base test class.
Also, avoiding the extra allocations for a closure by implementing a custom TCS.

Author: BrennanConroy
Assignees: -
Labels:

area-System.Threading

Milestone: -

@halter73
Copy link
Member

halter73 commented Feb 4, 2022

Also, avoiding the extra allocations for a closure by implementing a custom TCS.

Is the custom TCS really less expensive than the closure? I figured it'd be about the same.

@BrennanConroy
Copy link
Member Author

Without the custom tcs you have the normal TCS allocation + the closure allocation. With a custom tcs, you have the single class allocation, so basically a TCS with a couple extra fields.


private class WrappedTCS : TaskCompletionSource<RateLimitLease>
Copy link
Member

Choose a reason for hiding this comment

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

Can this type be moved to the base class? So it's doubled from ConcurrencyLimiter (almost).

Copy link
Member Author

@BrennanConroy BrennanConroy Feb 5, 2022

Choose a reason for hiding this comment

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

There is a lot of similar code between TokenBucket and ConcurrencyLimiter, planning on sharing a lot of it in a future change.


public void TryCancel()
{
if (TrySetException(new OperationCanceledException()))
Copy link
Member

Choose a reason for hiding this comment

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

Why this rather than TrySetCanceled()?

Copy link
Member

Choose a reason for hiding this comment

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

Here's some previous discussion: aspnet/AspLabs#387 (comment)

Given that we're doing return new ValueTask<RateLimitLease>(Task.FromCanceled<RateLimitLease>(cancellationToken)); instead of calling ThrowIfCancellationRequested(), that's even more reason to use TrySetCanceled() now here.

We should probably capture the cancellationToken too and call the TrySetCanceled(CancellationToken) overload.

Limiter = limiter;
}

public void TryCancel()
Copy link
Member

Choose a reason for hiding this comment

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

Nit: there's a minor (internal) usability issue here, as now there's a functional difference between TryCancel and TrySetCanceled, which sound very similar.

Copy link
Member Author

Choose a reason for hiding this comment

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

Would the recommended approach be to new override TrySetCanceled?

@BrennanConroy
Copy link
Member Author

Failures unrelated to the PR and tracked in #64963, merging.

@BrennanConroy BrennanConroy merged commit 21747c9 into dotnet:main Feb 10, 2022
@BrennanConroy BrennanConroy deleted the brecon/cancel branch February 10, 2022 23:27
@ghost ghost locked as resolved and limited conversation to collaborators Mar 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TokenBucketRateLimiter.WaitAsync() does not immediately reduce the _queueCount on cancellation
5 participants