コード例 #1
0
        public override async Task DropsMultipleOldestWhenQueuingMoreThanLimit_NewestFirst()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.NewestFirst, 2,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(2);

            Assert.True(lease.IsAcquired);
            var wait = limiter.WaitAndAcquireAsync(1);

            Assert.False(wait.IsCompleted);

            var wait2 = limiter.WaitAndAcquireAsync(1);

            Assert.False(wait2.IsCompleted);

            var wait3  = limiter.WaitAndAcquireAsync(2);
            var lease1 = await wait;
            var lease2 = await wait2;

            Assert.False(lease1.IsAcquired);
            Assert.False(lease2.IsAcquired);
            Assert.False(wait3.IsCompleted);

            limiter.TryReplenish();
            limiter.TryReplenish();

            lease = await wait3;
            Assert.True(lease.IsAcquired);
        }
コード例 #2
0
        public override async Task CanDequeueMultipleResourcesAtOnce()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.OldestFirst, 4,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));

            using var lease = await limiter.WaitAndAcquireAsync(2);

            Assert.True(lease.IsAcquired);

            var wait1 = limiter.WaitAndAcquireAsync(1);
            var wait2 = limiter.WaitAndAcquireAsync(1);

            Assert.False(wait1.IsCompleted);
            Assert.False(wait2.IsCompleted);

            lease.Dispose();
            Assert.True(limiter.TryReplenish());
            Assert.True(limiter.TryReplenish());

            var lease1 = await wait1;
            var lease2 = await wait2;

            Assert.True(lease1.IsAcquired);
            Assert.True(lease2.IsAcquired);
        }
コード例 #3
0
        public override async Task CanAcquireResourceAsync_QueuesAndGrabsNewest()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.NewestFirst, 3,
                                                                                           TimeSpan.FromMinutes(0), 2, autoReplenishment: false));

            var lease = await limiter.WaitAndAcquireAsync(2);

            Assert.True(lease.IsAcquired);

            var wait1 = limiter.WaitAndAcquireAsync(2);
            var wait2 = limiter.WaitAndAcquireAsync();

            Assert.False(wait1.IsCompleted);
            Assert.False(wait2.IsCompleted);

            lease.Dispose();
            Assert.True(limiter.TryReplenish());
            Assert.False(wait2.IsCompleted);

            Assert.True(limiter.TryReplenish());
            // second queued item completes first with NewestFirst
            lease = await wait2;
            Assert.True(lease.IsAcquired);
            Assert.False(wait1.IsCompleted);

            lease.Dispose();
            Assert.Equal(1, limiter.GetAvailablePermits());
            Assert.True(limiter.TryReplenish());
            Assert.True(limiter.TryReplenish());

            lease = await wait1;
            Assert.True(lease.IsAcquired);
        }
コード例 #4
0
        public override async Task CannotAcquireResourcesWithWaitAndAcquireAsyncWithQueuedItemsIfOldestFirst()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(3, QueueProcessingOrder.OldestFirst, 5,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));

            var lease = limiter.Acquire(3);

            Assert.True(lease.IsAcquired);

            var wait  = limiter.WaitAndAcquireAsync(2);
            var wait2 = limiter.WaitAndAcquireAsync(2);

            Assert.False(wait.IsCompleted);
            Assert.False(wait2.IsCompleted);

            limiter.TryReplenish();

            Assert.False(wait.IsCompleted);
            Assert.False(wait2.IsCompleted);

            limiter.TryReplenish();

            lease = await wait;
            Assert.True(lease.IsAcquired);

            limiter.TryReplenish();
            limiter.TryReplenish();

            lease = await wait2;
            Assert.True(lease.IsAcquired);
        }
コード例 #5
0
        public override async Task CancelUpdatesQueueLimit()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.NewestFirst, 1,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(2);

            Assert.True(lease.IsAcquired);

            var cts  = new CancellationTokenSource();
            var wait = limiter.WaitAndAcquireAsync(1, cts.Token);

            cts.Cancel();
            var ex = await Assert.ThrowsAsync <TaskCanceledException>(() => wait.AsTask());

            Assert.Equal(cts.Token, ex.CancellationToken);

            wait = limiter.WaitAndAcquireAsync(1);
            Assert.False(wait.IsCompleted);

            limiter.TryReplenish();
            limiter.TryReplenish();

            lease = await wait;
            Assert.True(lease.IsAcquired);
            Assert.Equal(1, limiter.GetAvailablePermits());
        }
コード例 #6
0
        public override async Task CanAcquireResourcesWithWaitAndAcquireAsyncWithQueuedItemsIfNewestFirst()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.NewestFirst, 2,
                                                                                           TimeSpan.Zero, 3, autoReplenishment: false));

            var lease = limiter.Acquire(1);

            Assert.True(lease.IsAcquired);

            var wait = limiter.WaitAndAcquireAsync(2);

            Assert.False(wait.IsCompleted);

            Assert.Equal(1, limiter.GetAvailablePermits());
            lease = await limiter.WaitAndAcquireAsync(1);

            Assert.True(lease.IsAcquired);
            Assert.False(wait.IsCompleted);

            limiter.TryReplenish();
            Assert.True(limiter.TryReplenish());

            Assert.False(wait.IsCompleted);

            Assert.True(limiter.TryReplenish());
            lease = await wait;
            Assert.True(lease.IsAcquired);
        }
コード例 #7
0
        public override async Task DisposeAsyncReleasesQueuedAcquires()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 3,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(1);
            var wait1 = limiter.WaitAndAcquireAsync(1);
            var wait2 = limiter.WaitAndAcquireAsync(1);
            var wait3 = limiter.WaitAndAcquireAsync(1);

            Assert.False(wait1.IsCompleted);
            Assert.False(wait2.IsCompleted);
            Assert.False(wait3.IsCompleted);

            await limiter.DisposeAsync();

            lease = await wait1;
            Assert.False(lease.IsAcquired);
            lease = await wait2;
            Assert.False(lease.IsAcquired);
            lease = await wait3;
            Assert.False(lease.IsAcquired);

            // Throws after disposal
            Assert.Throws <ObjectDisposedException>(() => limiter.Acquire(1));
            await Assert.ThrowsAsync <ObjectDisposedException>(() => limiter.WaitAndAcquireAsync(1).AsTask());
        }
コード例 #8
0
        public override async Task LargeAcquiresAndQueuesDoNotIntegerOverflow()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(int.MaxValue, QueueProcessingOrder.NewestFirst, int.MaxValue,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(int.MaxValue);

            Assert.True(lease.IsAcquired);

            // Fill queue
            var wait = limiter.WaitAndAcquireAsync(3);

            Assert.False(wait.IsCompleted);

            var wait2 = limiter.WaitAndAcquireAsync(int.MaxValue);

            Assert.False(wait2.IsCompleted);

            var lease1 = await wait;

            Assert.False(lease1.IsAcquired);

            limiter.TryReplenish();
            limiter.TryReplenish();
            var lease2 = await wait2;

            Assert.True(lease2.IsAcquired);
        }
コード例 #9
0
        public override async Task QueueAvailableAfterQueueLimitHitAndResources_BecomeAvailable()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(3, QueueProcessingOrder.OldestFirst, 2,
                                                                                           TimeSpan.Zero, 3, autoReplenishment: false));
            var lease = limiter.Acquire(2);
            var wait  = limiter.WaitAndAcquireAsync(2);

            var failedLease = await limiter.WaitAndAcquireAsync(2);

            Assert.False(failedLease.IsAcquired);

            limiter.TryReplenish();
            limiter.TryReplenish();
            Assert.False(wait.IsCompleted);

            limiter.TryReplenish();
            lease = await wait;
            Assert.True(lease.IsAcquired);

            wait = limiter.WaitAndAcquireAsync(2);
            Assert.False(wait.IsCompleted);

            limiter.TryReplenish();
            limiter.TryReplenish();
            limiter.TryReplenish();

            lease = await wait;
            Assert.True(lease.IsAcquired);
        }
コード例 #10
0
        public async Task CanAcquireMultipleRequestsAsync()
        {
            // This test verifies the following behavior
            // 1. when we have available permits after replenish to serve the queued requests
            // 2. when the oldest item from queue is remove to accommodate new requests (QueueProcessingOrder: NewestFirst)
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(4, QueueProcessingOrder.NewestFirst, 4,
                                                                                           TimeSpan.Zero, 3, autoReplenishment: false));

            using var lease = await limiter.WaitAndAcquireAsync(2);

            Assert.True(lease.IsAcquired);
            var wait = limiter.WaitAndAcquireAsync(3);

            Assert.False(wait.IsCompleted);

            Assert.True(limiter.TryReplenish());

            Assert.False(wait.IsCompleted);

            var wait2 = limiter.WaitAndAcquireAsync(2);

            Assert.True(wait2.IsCompleted);

            Assert.True(limiter.TryReplenish());

            var wait3 = limiter.WaitAndAcquireAsync(2);

            Assert.False(wait3.IsCompleted);

            Assert.True(limiter.TryReplenish());
            Assert.True((await wait3).IsAcquired);

            Assert.False((await wait).IsAcquired);
            Assert.Equal(0, limiter.GetAvailablePermits());
        }
コード例 #11
0
        public override async Task FailsWhenQueuingMoreThanLimit_OldestFirst()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));

            using var lease = limiter.Acquire(1);
            var wait = limiter.WaitAndAcquireAsync(1);

            var failedLease = await limiter.WaitAndAcquireAsync(1);

            Assert.False(failedLease.IsAcquired);
        }
コード例 #12
0
        public override async Task WaitAndAcquireAsyncZero_WithoutAvailabilityWaitsForAvailability()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = await limiter.WaitAndAcquireAsync(1);

            Assert.True(lease.IsAcquired);

            var wait = limiter.WaitAndAcquireAsync(0);

            Assert.False(wait.IsCompleted);

            lease.Dispose();
            Assert.True(limiter.TryReplenish());
            Assert.True(limiter.TryReplenish());
            using var lease2 = await wait;
            Assert.True(lease2.IsAcquired);
        }
コード例 #13
0
        public override async Task WaitAndAcquireAsyncZero_WithAvailability()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1,
                                                                                           TimeSpan.Zero, 1, autoReplenishment: false));

            using var lease = await limiter.WaitAndAcquireAsync(0);

            Assert.True(lease.IsAcquired);
        }
コード例 #14
0
        public async Task AutoReplenish_ReplenishesCounters()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.OldestFirst, 1,
                                                                                           TimeSpan.FromMilliseconds(1000), 2, autoReplenishment: true));

            Assert.Equal(2, limiter.GetAvailablePermits());
            limiter.Acquire(2);

            var lease = await limiter.WaitAndAcquireAsync(1);

            Assert.True(lease.IsAcquired);
        }
コード例 #15
0
        public override async Task DropsRequestedLeaseIfPermitCountGreaterThanQueueLimitAndNoAvailability_NewestFirst()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.NewestFirst, 1,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(2);

            Assert.True(lease.IsAcquired);

            // Fill queue
            var wait = limiter.WaitAndAcquireAsync(1);

            Assert.False(wait.IsCompleted);

            var lease1 = await limiter.WaitAndAcquireAsync(2);

            Assert.False(lease1.IsAcquired);

            limiter.TryReplenish();
            limiter.TryReplenish();

            lease = await wait;
            Assert.True(lease.IsAcquired);
        }
コード例 #16
0
        public override async Task CanAcquireResourceAsync()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.NewestFirst, 4,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));

            using var lease = await limiter.WaitAndAcquireAsync();

            Assert.True(lease.IsAcquired);
            var wait = limiter.WaitAndAcquireAsync(2);

            Assert.False(wait.IsCompleted);

            Assert.True(limiter.TryReplenish());

            Assert.False(wait.IsCompleted);

            var wait2 = limiter.WaitAndAcquireAsync(2);

            Assert.False(wait2.IsCompleted);

            Assert.True(limiter.TryReplenish());

            Assert.True((await wait2).IsAcquired);
        }
コード例 #17
0
        public override async Task CanFillQueueWithNewestFirstAfterCancelingQueuedRequestWithAnotherQueuedRequest()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.NewestFirst, 2,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(2);

            Assert.True(lease.IsAcquired);

            var cts  = new CancellationTokenSource();
            var wait = limiter.WaitAndAcquireAsync(1, cts.Token);

            // Add another item to queue, will be completed as failed later when we queue another item
            var wait2 = limiter.WaitAndAcquireAsync(1);

            Assert.False(wait.IsCompleted);

            cts.Cancel();
            var ex = await Assert.ThrowsAsync <TaskCanceledException>(() => wait.AsTask());

            Assert.Equal(cts.Token, ex.CancellationToken);

            lease.Dispose();
            limiter.TryReplenish();

            var wait3 = limiter.WaitAndAcquireAsync(2);

            Assert.False(wait3.IsCompleted);

            // will be kicked by wait3 because we're using NewestFirst
            lease = await wait2;
            Assert.False(lease.IsAcquired);

            limiter.TryReplenish();
            lease = await wait3;
            Assert.True(lease.IsAcquired);
        }
コード例 #18
0
        public override async Task CanDisposeAfterCancelingQueuedRequest()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(1);

            Assert.True(lease.IsAcquired);

            var cts  = new CancellationTokenSource();
            var wait = limiter.WaitAndAcquireAsync(1, cts.Token);

            cts.Cancel();
            var ex = await Assert.ThrowsAsync <TaskCanceledException>(() => wait.AsTask());

            Assert.Equal(cts.Token, ex.CancellationToken);

            // Make sure dispose doesn't have any side-effects when dealing with a canceled queued item
            limiter.Dispose();
        }
コード例 #19
0
        public override async Task CanCancelWaitAndAcquireAsyncBeforeQueuing()
        {
            var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(2, QueueProcessingOrder.OldestFirst, 1,
                                                                                           TimeSpan.Zero, 2, autoReplenishment: false));
            var lease = limiter.Acquire(2);

            Assert.True(lease.IsAcquired);

            var cts = new CancellationTokenSource();

            cts.Cancel();

            var ex = await Assert.ThrowsAsync <TaskCanceledException>(() => limiter.WaitAndAcquireAsync(1, cts.Token).AsTask());

            Assert.Equal(cts.Token, ex.CancellationToken);

            lease.Dispose();
            Assert.True(limiter.TryReplenish());

            Assert.Equal(0, limiter.GetAvailablePermits());
        }
コード例 #20
0
 public override async Task ThrowsWhenWaitingForLessThanZero()
 {
     var limiter = new SlidingWindowRateLimiter(new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1,
                                                                                    TimeSpan.Zero, 1, autoReplenishment: false));
     await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await limiter.WaitAndAcquireAsync(-1));
 }