public async Task Create_BlockingWaitDoesNotBlockOtherPartitions() { var limiterFactory = new TrackingRateLimiterFactory <int>(); using var limiter = PartitionedRateLimiter.Create <string, int>(resource => { if (resource == "1") { return(RateLimitPartition.Create(1, key => limiterFactory.GetLimiter(key))); } return(RateLimitPartition.CreateConcurrencyLimiter(2, _ => new ConcurrencyLimiterOptions(1, QueueProcessingOrder.OldestFirst, 2))); }); var lease = await limiter.WaitAsync("2"); var wait = limiter.WaitAsync("2"); Assert.False(wait.IsCompleted); // Different partition, should not be blocked by the wait in the other partition await limiter.WaitAsync("1"); lease.Dispose(); await wait; Assert.Equal(1, limiterFactory.Limiters.Count); Assert.Equal(0, limiterFactory.Limiters[0].Limiter.AcquireCallCount); Assert.Equal(1, limiterFactory.Limiters[0].Limiter.WaitAsyncCallCount); }
public void Create_Concurrency() { var options = new ConcurrencyLimiterOptions(10, QueueProcessingOrder.OldestFirst, 10); var partition = RateLimitPartition.CreateConcurrencyLimiter(1, key => options); var limiter = partition.Factory(1); var concurrencyLimiter = Assert.IsType <ConcurrencyLimiter>(limiter); Assert.Equal(options.PermitLimit, concurrencyLimiter.GetAvailablePermits()); }
public void Create_Concurrency() { var options = new ConcurrencyLimiterOptions(10, QueueProcessingOrder.OldestFirst, 10); var partition = RateLimitPartition.CreateConcurrencyLimiter(1, key => options); var factoryProperty = typeof(RateLimitPartition <int>).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance) !; var factory = (Func <int, RateLimiter>)factoryProperty.GetValue(partition); var limiter = factory(1); var concurrencyLimiter = Assert.IsType <ConcurrencyLimiter>(limiter); Assert.Equal(options.PermitLimit, concurrencyLimiter.GetAvailablePermits()); }
public async Task Create_CancellationTokenPassedToUnderlyingLimiter() { using var limiter = PartitionedRateLimiter.Create <string, int>(resource => { return(RateLimitPartition.CreateConcurrencyLimiter(1, _ => new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1))); }); var lease = limiter.Acquire(""); Assert.True(lease.IsAcquired); var cts = new CancellationTokenSource(); var waitTask = limiter.WaitAsync("", 1, cts.Token); Assert.False(waitTask.IsCompleted); cts.Cancel(); await Assert.ThrowsAsync <TaskCanceledException>(async() => await waitTask); }