Skip to content

Commit

Permalink
fix: rename request count to permit count (#76558)
Browse files Browse the repository at this point in the history
  • Loading branch information
AliKhalili committed Oct 5, 2022
1 parent 0bbd48d commit 3e347d7
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public FixedWindowRateLimiter(System.Threading.RateLimiting.FixedWindowRateLimit
public override System.TimeSpan? IdleDuration { get { throw null; } }
public override bool IsAutoReplenishing { get { throw null; } }
public override System.TimeSpan ReplenishmentPeriod { get { throw null; } }
protected override System.Threading.Tasks.ValueTask<System.Threading.RateLimiting.RateLimitLease> AcquireAsyncCore(int requestCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
protected override System.Threading.RateLimiting.RateLimitLease AttemptAcquireCore(int requestCount) { throw null; }
protected override System.Threading.Tasks.ValueTask<System.Threading.RateLimiting.RateLimitLease> AcquireAsyncCore(int permitCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
protected override System.Threading.RateLimiting.RateLimitLease AttemptAcquireCore(int permitCount) { throw null; }
protected override void Dispose(bool disposing) { }
protected override System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; }
public override System.Threading.RateLimiting.RateLimiterStatistics? GetStatistics() { throw null; }
Expand Down Expand Up @@ -150,8 +150,8 @@ public SlidingWindowRateLimiter(System.Threading.RateLimiting.SlidingWindowRateL
public override System.TimeSpan? IdleDuration { get { throw null; } }
public override bool IsAutoReplenishing { get { throw null; } }
public override System.TimeSpan ReplenishmentPeriod { get { throw null; } }
protected override System.Threading.Tasks.ValueTask<System.Threading.RateLimiting.RateLimitLease> AcquireAsyncCore(int requestCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
protected override System.Threading.RateLimiting.RateLimitLease AttemptAcquireCore(int requestCount) { throw null; }
protected override System.Threading.Tasks.ValueTask<System.Threading.RateLimiting.RateLimitLease> AcquireAsyncCore(int permitCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
protected override System.Threading.RateLimiting.RateLimitLease AttemptAcquireCore(int permitCount) { throw null; }
protected override void Dispose(bool disposing) { }
protected override System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; }
public override System.Threading.RateLimiting.RateLimiterStatistics? GetStatistics() { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace System.Threading.RateLimiting
/// </summary>
public sealed class FixedWindowRateLimiter : ReplenishingRateLimiter
{
private int _requestCount;
private int _permitCount;
private int _queueCount;
private long _lastReplenishmentTick;
private long? _idleSince;
Expand Down Expand Up @@ -73,7 +73,7 @@ public FixedWindowRateLimiter(FixedWindowRateLimiterOptions options)
AutoReplenishment = options.AutoReplenishment
};

_requestCount = options.PermitLimit;
_permitCount = options.PermitLimit;

_idleSince = _lastReplenishmentTick = Stopwatch.GetTimestamp();

Expand All @@ -89,80 +89,80 @@ public FixedWindowRateLimiter(FixedWindowRateLimiterOptions options)
ThrowIfDisposed();
return new RateLimiterStatistics()
{
CurrentAvailablePermits = _requestCount,
CurrentAvailablePermits = _permitCount,
CurrentQueuedCount = _queueCount,
TotalFailedLeases = Interlocked.Read(ref _failedLeasesCount),
TotalSuccessfulLeases = Interlocked.Read(ref _successfulLeasesCount),
};
}

/// <inheritdoc/>
protected override RateLimitLease AttemptAcquireCore(int requestCount)
protected override RateLimitLease AttemptAcquireCore(int permitCount)
{
// These amounts of resources can never be acquired
// Raises a PermitLimitExceeded ArgumentOutOFRangeException
if (requestCount > _options.PermitLimit)
if (permitCount > _options.PermitLimit)
{
throw new ArgumentOutOfRangeException(nameof(requestCount), requestCount, SR.Format(SR.PermitLimitExceeded, requestCount, _options.PermitLimit));
throw new ArgumentOutOfRangeException(nameof(permitCount), permitCount, SR.Format(SR.PermitLimitExceeded, permitCount, _options.PermitLimit));
}

// Return SuccessfulLease or FailedLease depending to indicate limiter state
if (requestCount == 0 && !_disposed)
if (permitCount == 0 && !_disposed)
{
// Check if the requests are permitted in a window
// Requests will be allowed if the total served request is less than the max allowed requests (permit limit).
if (_requestCount > 0)
if (_permitCount > 0)
{
Interlocked.Increment(ref _successfulLeasesCount);
return SuccessfulLease;
}

Interlocked.Increment(ref _failedLeasesCount);
return CreateFailedWindowLease(requestCount);
return CreateFailedWindowLease(permitCount);
}

lock (Lock)
{
if (TryLeaseUnsynchronized(requestCount, out RateLimitLease? lease))
if (TryLeaseUnsynchronized(permitCount, out RateLimitLease? lease))
{
return lease;
}

Interlocked.Increment(ref _failedLeasesCount);
return CreateFailedWindowLease(requestCount);
return CreateFailedWindowLease(permitCount);
}
}

/// <inheritdoc/>
protected override ValueTask<RateLimitLease> AcquireAsyncCore(int requestCount, CancellationToken cancellationToken = default)
protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, CancellationToken cancellationToken = default)
{
// These amounts of resources can never be acquired
if (requestCount > _options.PermitLimit)
if (permitCount > _options.PermitLimit)
{
throw new ArgumentOutOfRangeException(nameof(requestCount), requestCount, SR.Format(SR.PermitLimitExceeded, requestCount, _options.PermitLimit));
throw new ArgumentOutOfRangeException(nameof(permitCount), permitCount, SR.Format(SR.PermitLimitExceeded, permitCount, _options.PermitLimit));
}

ThrowIfDisposed();

// Return SuccessfulAcquisition if requestCount is 0 and resources are available
if (requestCount == 0 && _requestCount > 0)
// Return SuccessfulAcquisition if permitCount is 0 and resources are available
if (permitCount == 0 && _permitCount > 0)
{
Interlocked.Increment(ref _successfulLeasesCount);
return new ValueTask<RateLimitLease>(SuccessfulLease);
}

lock (Lock)
{
if (TryLeaseUnsynchronized(requestCount, out RateLimitLease? lease))
if (TryLeaseUnsynchronized(permitCount, out RateLimitLease? lease))
{
return new ValueTask<RateLimitLease>(lease);
}

// Avoid integer overflow by using subtraction instead of addition
Debug.Assert(_options.QueueLimit >= _queueCount);
if (_options.QueueLimit - _queueCount < requestCount)
if (_options.QueueLimit - _queueCount < permitCount)
{
if (_options.QueueProcessingOrder == QueueProcessingOrder.NewestFirst && requestCount <= _options.QueueLimit)
if (_options.QueueProcessingOrder == QueueProcessingOrder.NewestFirst && permitCount <= _options.QueueLimit)
{
// remove oldest items from queue until there is space for the newest acquisition request
do
Expand All @@ -179,17 +179,17 @@ protected override ValueTask<RateLimitLease> AcquireAsyncCore(int requestCount,
Interlocked.Increment(ref _failedLeasesCount);
}
}
while (_options.QueueLimit - _queueCount < requestCount);
while (_options.QueueLimit - _queueCount < permitCount);
}
else
{
Interlocked.Increment(ref _failedLeasesCount);
// Don't queue if queue limit reached and QueueProcessingOrder is OldestFirst
return new ValueTask<RateLimitLease>(CreateFailedWindowLease(requestCount));
return new ValueTask<RateLimitLease>(CreateFailedWindowLease(permitCount));
}
}

CancelQueueState tcs = new CancelQueueState(requestCount, this, cancellationToken);
CancelQueueState tcs = new CancelQueueState(permitCount, this, cancellationToken);
CancellationTokenRegistration ctr = default;
if (cancellationToken.CanBeCanceled)
{
Expand All @@ -199,32 +199,32 @@ protected override ValueTask<RateLimitLease> AcquireAsyncCore(int requestCount,
}, tcs);
}

RequestRegistration registration = new RequestRegistration(requestCount, tcs, ctr);
RequestRegistration registration = new RequestRegistration(permitCount, tcs, ctr);
_queue.EnqueueTail(registration);
_queueCount += requestCount;
_queueCount += permitCount;
Debug.Assert(_queueCount <= _options.QueueLimit);

return new ValueTask<RateLimitLease>(registration.Tcs.Task);
}
}

private RateLimitLease CreateFailedWindowLease(int requestCount)
private RateLimitLease CreateFailedWindowLease(int permitCount)
{
int replenishAmount = requestCount - _requestCount + _queueCount;
int replenishAmount = permitCount - _permitCount + _queueCount;
// can't have 0 replenish window, that would mean it should be a successful lease
int replenishWindow = Math.Max(replenishAmount / _options.PermitLimit, 1);

return new FixedWindowLease(false, TimeSpan.FromTicks(_options.Window.Ticks * replenishWindow));
}

private bool TryLeaseUnsynchronized(int requestCount, [NotNullWhen(true)] out RateLimitLease? lease)
private bool TryLeaseUnsynchronized(int permitCount, [NotNullWhen(true)] out RateLimitLease? lease)
{
ThrowIfDisposed();

// if permitCount is 0 we want to queue it if there are no available permits
if (_requestCount >= requestCount && _requestCount != 0)
if (_permitCount >= permitCount && _permitCount != 0)
{
if (requestCount == 0)
if (permitCount == 0)
{
Interlocked.Increment(ref _successfulLeasesCount);
// Edge case where the check before the lock showed 0 available permit counters but when we got the lock, some permits were now available
Expand All @@ -237,8 +237,8 @@ private bool TryLeaseUnsynchronized(int requestCount, [NotNullWhen(true)] out Ra
if (_queueCount == 0 || (_queueCount > 0 && _options.QueueProcessingOrder == QueueProcessingOrder.NewestFirst))
{
_idleSince = null;
_requestCount -= requestCount;
Debug.Assert(_requestCount >= 0);
_permitCount -= permitCount;
Debug.Assert(_permitCount >= 0);
Interlocked.Increment(ref _successfulLeasesCount);
lease = SuccessfulLease;
return true;
Expand Down Expand Up @@ -294,15 +294,15 @@ private void ReplenishInternal(long nowTicks)

_lastReplenishmentTick = nowTicks;

int availableRequestCounters = _requestCount;
int availablePermitCounters = _permitCount;

if (availableRequestCounters >= _options.PermitLimit)
if (availablePermitCounters >= _options.PermitLimit)
{
// All counters available, nothing to do
return;
}

_requestCount = _options.PermitLimit;
_permitCount = _options.PermitLimit;

// Process queued requests
while (_queue.Count > 0)
Expand All @@ -312,7 +312,7 @@ private void ReplenishInternal(long nowTicks)
? _queue.PeekHead()
: _queue.PeekTail();

if (_requestCount >= nextPendingRequest.Count)
if (_permitCount >= nextPendingRequest.Count)
{
// Request can be fulfilled
nextPendingRequest =
Expand All @@ -321,13 +321,13 @@ private void ReplenishInternal(long nowTicks)
: _queue.DequeueTail();

_queueCount -= nextPendingRequest.Count;
_requestCount -= nextPendingRequest.Count;
Debug.Assert(_requestCount >= 0);
_permitCount -= nextPendingRequest.Count;
Debug.Assert(_permitCount >= 0);

if (!nextPendingRequest.Tcs.TrySetResult(SuccessfulLease))
{
// Queued item was canceled so add count back
_requestCount += nextPendingRequest.Count;
_permitCount += nextPendingRequest.Count;
// Updating queue count is handled by the cancellation code
_queueCount += nextPendingRequest.Count;
}
Expand All @@ -345,7 +345,7 @@ private void ReplenishInternal(long nowTicks)
}
}

if (_requestCount == _options.PermitLimit)
if (_permitCount == _options.PermitLimit)
{
Debug.Assert(_idleSince is null);
Debug.Assert(_queueCount == 0);
Expand Down Expand Up @@ -426,9 +426,9 @@ public override bool TryGetMetadata(string metadataName, out object? metadata)

private readonly struct RequestRegistration
{
public RequestRegistration(int requestCount, TaskCompletionSource<RateLimitLease> tcs, CancellationTokenRegistration cancellationTokenRegistration)
public RequestRegistration(int permitCount, TaskCompletionSource<RateLimitLease> tcs, CancellationTokenRegistration cancellationTokenRegistration)
{
Count = requestCount;
Count = permitCount;
// Use VoidAsyncOperationWithData<T> instead
Tcs = tcs;
CancellationTokenRegistration = cancellationTokenRegistration;
Expand All @@ -443,14 +443,14 @@ public RequestRegistration(int requestCount, TaskCompletionSource<RateLimitLease

private sealed class CancelQueueState : TaskCompletionSource<RateLimitLease>
{
private readonly int _requestCount;
private readonly int _permitCount;
private readonly FixedWindowRateLimiter _limiter;
private readonly CancellationToken _cancellationToken;

public CancelQueueState(int requestCount, FixedWindowRateLimiter limiter, CancellationToken cancellationToken)
public CancelQueueState(int permitCount, FixedWindowRateLimiter limiter, CancellationToken cancellationToken)
: base(TaskCreationOptions.RunContinuationsAsynchronously)
{
_requestCount = requestCount;
_permitCount = permitCount;
_limiter = limiter;
_cancellationToken = cancellationToken;
}
Expand All @@ -461,7 +461,7 @@ public CancelQueueState(int requestCount, FixedWindowRateLimiter limiter, Cancel
{
lock (_limiter.Lock)
{
_limiter._queueCount -= _requestCount;
_limiter._queueCount -= _permitCount;
}
return true;
}
Expand Down
Loading

0 comments on commit 3e347d7

Please sign in to comment.