Skip to content

Commit

Permalink
Merge pull request #94 from cristipufu/fix/thread_pool_exhaust
Browse files Browse the repository at this point in the history
Remove sync impl
  • Loading branch information
cristipufu authored Sep 15, 2023
2 parents e464370 + ccb95be commit fc8ebc2
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 91 deletions.
24 changes: 2 additions & 22 deletions src/RedisRateLimiting/Concurrency/RedisConcurrencyRateLimiter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,7 @@ protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, C

protected override RateLimitLease AttemptAcquireCore(int permitCount)
{
if (permitCount > _options.PermitLimit)
{
throw new ArgumentOutOfRangeException(nameof(permitCount), permitCount, string.Format("{0} permit(s) exceeds the permit limit of {1}.", permitCount, _options.PermitLimit));
}

var leaseContext = new ConcurencyLeaseContext
{
Limit = _options.PermitLimit,
RequestId = Guid.NewGuid().ToString(),
};

var response = _redisManager.TryAcquireLease(leaseContext.RequestId);

leaseContext.Count = response.Count;

if (response.Allowed)
{
return new ConcurrencyLease(isAcquired: true, this, leaseContext);
}

return new ConcurrencyLease(isAcquired: false, this, leaseContext);
return FailedLease;
}

private async ValueTask<RateLimitLease> AcquireAsyncCoreInternal(CancellationToken cancellationToken)
Expand Down Expand Up @@ -148,7 +128,7 @@ private void Release(ConcurencyLeaseContext leaseContext)
{
if (leaseContext.RequestId is null) return;

_redisManager.ReleaseLease(leaseContext.RequestId);
_ = _redisManager.ReleaseLeaseAsync(leaseContext.RequestId);
}

private async Task StartDequeueTimerAsync(PeriodicTimer periodicTimer)
Expand Down
26 changes: 3 additions & 23 deletions src/RedisRateLimiting/FixedWindow/RedisFixedWindowRateLimiter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class RedisFixedWindowRateLimiter<TKey> : RateLimiter
private readonly RedisFixedWindowManager _redisManager;
private readonly RedisFixedWindowRateLimiterOptions _options;

private readonly FixedWindowLease FailedLease = new(isAcquired: false, null);

public override TimeSpan? IdleDuration => TimeSpan.Zero;

public RedisFixedWindowRateLimiter(TKey partitionKey, RedisFixedWindowRateLimiterOptions options)
Expand Down Expand Up @@ -60,29 +62,7 @@ protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, C

protected override RateLimitLease AttemptAcquireCore(int permitCount)
{
if (permitCount > _options.PermitLimit)
{
throw new ArgumentOutOfRangeException(nameof(permitCount), permitCount, string.Format("{0} permit(s) exceeds the permit limit of {1}.", permitCount, _options.PermitLimit));
}

var leaseContext = new FixedWindowLeaseContext
{
Limit = _options.PermitLimit,
Window = _options.Window,
};

var response = _redisManager.TryAcquireLease();

leaseContext.Count = response.Count;
leaseContext.RetryAfter = response.RetryAfter;
leaseContext.ExpiresAt = DateTimeOffset.FromUnixTimeSeconds(response.ExpiresAt);

if (leaseContext.Count > _options.PermitLimit)
{
return new FixedWindowLease(isAcquired: false, leaseContext);
}

return new FixedWindowLease(isAcquired: true, leaseContext);
return FailedLease;
}

private async ValueTask<RateLimitLease> AcquireAsyncCoreInternal()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ public class RedisSlidingWindowRateLimiter<TKey> : RateLimiter
{
private readonly RedisSlidingWindowManager _redisManager;
private readonly RedisSlidingWindowRateLimiterOptions _options;


private readonly SlidingWindowLease FailedLease = new(isAcquired: false, null);

public override TimeSpan? IdleDuration => TimeSpan.Zero;

public RedisSlidingWindowRateLimiter(TKey partitionKey, RedisSlidingWindowRateLimiterOptions options)
Expand Down Expand Up @@ -60,29 +62,7 @@ protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, C

protected override RateLimitLease AttemptAcquireCore(int permitCount)
{
if (permitCount > _options.PermitLimit)
{
throw new ArgumentOutOfRangeException(nameof(permitCount), permitCount, string.Format("{0} permit(s) exceeds the permit limit of {1}.", permitCount, _options.PermitLimit));
}

var leaseContext = new SlidingWindowLeaseContext
{
Limit = _options.PermitLimit,
Window = _options.Window,
RequestId = Guid.NewGuid().ToString(),
};

var response = _redisManager.TryAcquireLease(leaseContext.RequestId);

leaseContext.Count = response.Count;
leaseContext.Allowed = response.Allowed;

if (leaseContext.Allowed)
{
return new SlidingWindowLease(isAcquired: true, leaseContext);
}

return new SlidingWindowLease(isAcquired: false, leaseContext);
return FailedLease;
}

private async ValueTask<RateLimitLease> AcquireAsyncCoreInternal()
Expand Down
25 changes: 3 additions & 22 deletions src/RedisRateLimiting/TokenBucket/RedisTokenBucketRateLimiter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public class RedisTokenBucketRateLimiter<TKey> : RateLimiter
private readonly RedisTokenBucketManager _redisManager;
private readonly RedisTokenBucketRateLimiterOptions _options;

private readonly TokenBucketLease FailedLease = new(isAcquired: false, null);

public override TimeSpan? IdleDuration => TimeSpan.Zero;

public RedisTokenBucketRateLimiter(TKey partitionKey, RedisTokenBucketRateLimiterOptions options)
Expand Down Expand Up @@ -65,28 +67,7 @@ protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, C

protected override RateLimitLease AttemptAcquireCore(int permitCount)
{
if (permitCount > _options.TokenLimit)
{
throw new ArgumentOutOfRangeException(nameof(permitCount), permitCount, string.Format("{0} permit(s) exceeds the permit limit of {1}.", permitCount, _options.TokenLimit));
}

var leaseContext = new TokenBucketLeaseContext
{
Limit = _options.TokenLimit,
};

var response = _redisManager.TryAcquireLease();

leaseContext.Allowed = response.Allowed;
leaseContext.Count = response.Count;
leaseContext.RetryAfter = response.RetryAfter;

if (leaseContext.Allowed)
{
return new TokenBucketLease(isAcquired: true, leaseContext);
}

return new TokenBucketLease(isAcquired: false, leaseContext);
return FailedLease;
}

private async ValueTask<RateLimitLease> AcquireAsyncCoreInternal()
Expand Down

0 comments on commit fc8ebc2

Please sign in to comment.