public override async Task CanDequeueMultipleResourcesAtOnce()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(2, QueueProcessingOrder.OldestFirst, 2));

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

            Assert.True(lease.IsAcquired);

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

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

            lease.Dispose();

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

            Assert.True(lease1.IsAcquired);
            Assert.True(lease2.IsAcquired);
        }
Beispiel #2
0
        public override async Task CancelUpdatesQueueLimit()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1));
            var lease   = limiter.Acquire(1);

            Assert.True(lease.IsAcquired);

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

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

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

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

            lease.Dispose();
            lease = await wait;
            Assert.True(lease.IsAcquired);
        }
        public override async Task CanAcquireResourceAsync_QueuesAndGrabsOldest()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.OldestFirst, 2));
            var lease   = await limiter.WaitAsync();

            Assert.True(lease.IsAcquired);
            var wait1 = limiter.WaitAsync();
            var wait2 = limiter.WaitAsync();

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

            lease.Dispose();

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

            lease.Dispose();

            lease = await wait2;
            Assert.True(lease.IsAcquired);
        }
        public override async Task QueueAvailableAfterQueueLimitHitAndResources_BecomeAvailable()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
            var lease   = limiter.Acquire(1);
            var wait    = limiter.WaitAsync(1);

            var failedLease = await limiter.WaitAsync(1).DefaultTimeout();

            Assert.False(failedLease.IsAcquired);

            lease.Dispose();
            lease = await wait.DefaultTimeout();

            Assert.True(lease.IsAcquired);

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

            lease.Dispose();
            lease = await wait.DefaultTimeout();

            Assert.True(lease.IsAcquired);
        }
        public override async Task CanAcquireResourceAsync_QueuesAndGrabsNewest()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(2, QueueProcessingOrder.NewestFirst, 3));
            var lease   = await limiter.WaitAsync(2);

            Assert.True(lease.IsAcquired);
            var wait1 = limiter.WaitAsync(2);
            var wait2 = limiter.WaitAsync();

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

            lease.Dispose();

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

            lease.Dispose();

            lease = await wait1;
            Assert.True(lease.IsAcquired);
        }
        public override async Task CanAcquireResourcesWithAcquireWithQueuedItemsIfNewestFirst()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(2, QueueProcessingOrder.NewestFirst, 3));

            using var lease = await limiter.WaitAsync(1);

            Assert.True(lease.IsAcquired);

            var wait1 = limiter.WaitAsync(2);

            Assert.False(wait1.IsCompleted);
            var lease2 = limiter.Acquire(1);

            Assert.True(lease2.IsAcquired);

            lease.Dispose();

            Assert.False(wait1.IsCompleted);
            lease2.Dispose();

            var lease1 = await wait1;

            Assert.True(lease1.IsAcquired);
        }
        public async Task ReasonMetadataOnFailedWaitAsync()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(2, QueueProcessingOrder.OldestFirst, 1));

            using var lease = limiter.Acquire(2);

            var failedLease = await limiter.WaitAsync(2);

            Assert.False(failedLease.IsAcquired);
            Assert.True(failedLease.TryGetMetadata(MetadataName.ReasonPhrase.Name, out var metadata));
            Assert.Equal("Queue limit reached", metadata);

            Assert.True(failedLease.TryGetMetadata(MetadataName.ReasonPhrase, out var typedMetadata));
            Assert.Equal("Queue limit reached", typedMetadata);
            Assert.Collection(failedLease.MetadataNames, item => item.Equals(MetadataName.ReasonPhrase.Name));
        }
        public override async Task CanCancelWaitAsyncBeforeQueuing()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1));
            var lease   = limiter.Acquire(1);

            Assert.True(lease.IsAcquired);

            var cts = new CancellationTokenSource();

            cts.Cancel();

            await Assert.ThrowsAsync <OperationCanceledException>(() => limiter.WaitAsync(1, cts.Token).DefaultTimeout());

            lease.Dispose();

            Assert.Equal(1, limiter.GetAvailablePermits());
        }
        public override async Task CanDisposeAfterCancelingQueuedRequest()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1));
            var lease   = limiter.Acquire(1);

            Assert.True(lease.IsAcquired);

            var cts  = new CancellationTokenSource();
            var wait = limiter.WaitAsync(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();
        }
        public override async Task CanCancelWaitAsyncAfterQueuing()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1));
            var lease   = limiter.Acquire(1);

            Assert.True(lease.IsAcquired);

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

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

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

            lease.Dispose();

            Assert.Equal(1, limiter.GetAvailablePermits());
        }
 public override async Task ThrowsWhenWaitingForLessThanZero()
 {
     var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
     await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await limiter.WaitAsync(-1));
 }
        public override async Task ThrowsWhenWaitingForMoreThanLimit()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
            var ex      = await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await limiter.WaitAsync(2));

            Assert.Equal("permitCount", ex.ParamName);
        }