-
Notifications
You must be signed in to change notification settings - Fork 356
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
ConcurrencyLimiter implementation #387
Conversation
lock (_lock) | ||
{ | ||
// REVIEW: failed lease or exception? | ||
tcs.TrySetResult(FailedLease); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a OperationCanceledException/TaskCanceledException or a failed lease with a reason phrase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably capture the CancellationToken when we UnsafeRegister and either call tcs.TrySetCanceled(token)
or tcs.TrySetException(new OperationCanceledException(token))
. I don't have a big preference for which one. CancellationToken.ThrowIfCancellationRequested()
throws an OperationCanceledException though, and we should probably be doing that at the start of WaitAsyncCore, so maybe we should use an OperationCanceledExceptoin for consistency.
@@ -27,6 +42,7 @@ public bool TryGetMetadata<T>(MetadataName<T> metadataName, [MaybeNullWhen(false | |||
var successful = TryGetMetadata(metadataName.Name, out var rawMetadata); | |||
if (successful) | |||
{ | |||
// TODO: is null metadata allowed? | |||
metadata = rawMetadata is null ? default : (T)rawMetadata; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think null metadata should be allowed when returning true
. I think in API review we decided T
should not be nullable. MaybeNullWhen should only apply to non-nullable attributes anyway. If this was supposed to be nullable, we'd use [NotNullWhen(true)]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API review also said a null metadata is valid, but how do you represent that in generic code? Do we just hide the compiler warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't recall API review saying null metadata was valid except when TryGetMetadata returns false, but the signatures of the non-generic TryGetMetadata and GetAllMetadata make me wonder.
There shouldn't be a compiler warning since we're using [MaybeNullWhen(false)]
.
Specifies that when a method returns ReturnValue, the parameter may be null even if the corresponding type disallows it.
Emphasis mine. The signature in the API proposal is public bool TryGetMetadata<T>(MetadataName<T> metadataName, [MaybeNullWhen(false)] out T metadata);
with no T?
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I might remember us discussing allowing null
to distinguish between metadata that is normally defined but not present (returns true but gives null) vs metadata that is never present (returns false and gives null). If that's the case, the signature should probably just be public bool TryGetMetadata<T>(MetadataName<T> metadataName, [MaybeNull] out T metadata)
. This way value types don't need to be wrapped in Nullable.
{ | ||
throw new ArgumentOutOfRangeException(); | ||
throw new InvalidOperationException($"{permitCount} permits exceeds the permit limit of {_options.PermitLimit}."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Since I can't unresolve the previous conversation, starting a new one here)
I'm not sure I buy the above analysis (I know it came from API review). Looking at the Example of ArgumentOutOfRangeException in the docs doesn't follow this reasoning. There is no property that specifies a "min age" in that example.
Same goes for the wording on https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/using-standard-exception-types#argumentexception-argumentnullexception-and-argumentoutofrangeexception.
if bad arguments are passed to a member
Lastly, the base RateLimiter.WaitAsync
xml doc documents the ArgumentOutOfRangeException
. But it doesn't document InvalidOperationException
. Following the same reasoning as above, a caller to RateLimiter.WaitAsync
wouldn't know to catch InvalidOperationException
if it passed in too big of a permitCount
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like your arguments and will revert back to ArgumentOutOfRangeException with an error message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No description provided.