Exemplo n.º 1
0
        public override void NullIdleDurationWhenActive()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 1
            });

            using var lease = limiter.AttemptAcquire(1);
            Assert.Null(limiter.IdleDuration);
        }
Exemplo n.º 2
0
        public override void CanAcquireResource()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
            var lease   = limiter.Acquire();

            Assert.True(lease.IsAcquired);
            Assert.False(limiter.Acquire().IsAcquired);

            lease.Dispose();

            Assert.True(limiter.Acquire().IsAcquired);
        }
Exemplo n.º 3
0
        public override void NoMetadataOnAcquiredLease()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 1
            });

            using var lease = limiter.AttemptAcquire(1);
            Assert.False(lease.TryGetMetadata(MetadataName.ReasonPhrase.Name, out _));
        }
Exemplo n.º 4
0
        public override void MetadataNamesContainsAllMetadata()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 1
            });

            using var lease = limiter.AttemptAcquire(1);
            Assert.Collection(lease.MetadataNames, metadataName => Assert.Equal(metadataName, MetadataName.ReasonPhrase.Name));
        }
Exemplo n.º 5
0
        public override void AcquireZero_WithAvailability()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
                QueueLimit           = 1
            });

            using var lease = limiter.AttemptAcquire(0);
            Assert.True(lease.IsAcquired);
        }
Exemplo n.º 6
0
        public override void AcquireZero_WithoutAvailability()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));

            using var lease = limiter.Acquire(1);
            Assert.True(lease.IsAcquired);

            var lease2 = limiter.Acquire(0);

            Assert.False(lease2.IsAcquired);
            lease2.Dispose();
        }
Exemplo n.º 7
0
        public override async Task ThrowsWhenWaitingForMoreThanLimit()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
                QueueLimit           = 1
            });
            var ex = await Assert.ThrowsAsync <ArgumentOutOfRangeException>(async() => await limiter.AcquireAsync(2));

            Assert.Equal("permitCount", ex.ParamName);
        }
Exemplo n.º 8
0
        public override void ThrowsWhenAcquiringMoreThanLimit()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
                QueueLimit           = 1
            });
            var ex = Assert.Throws <ArgumentOutOfRangeException>(() => limiter.AttemptAcquire(2));

            Assert.Equal("permitCount", ex.ParamName);
        }
Exemplo n.º 9
0
        public override void GetStatisticsThrowsAfterDispose()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 100,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 50
            });

            limiter.Dispose();
            Assert.Throws <ObjectDisposedException>(limiter.GetStatistics);
        }
Exemplo n.º 10
0
        public override async Task AcquireAsyncZero_WithAvailability()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
                QueueLimit           = 1
            });

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

            Assert.True(lease.IsAcquired);
        }
Exemplo n.º 11
0
        public override void IdleDurationUpdatesWhenChangingFromActive()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 1
            });
            var lease = limiter.AttemptAcquire(1);

            lease.Dispose();
            Assert.NotNull(limiter.IdleDuration);
        }
Exemplo n.º 12
0
 protected virtual ProcessingResult Processing(bool processActions)
 {
     using (var entry = ConcurrencyLimiter.TryEnter())
     {
         ProcessingResult result = entry.HasEntry ? ProcessingResult.Processed : ProcessingResult.ExclusiveSkip;
         NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.Processing, result);
         if (result == ProcessingResult.Processed)
         {
             ExclusiveProcessing(processActions);
         }
         return(result);
     }
 }
Exemplo n.º 13
0
        public override async Task CanAcquireResourceAsync()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
            var lease   = await limiter.WaitAsync();

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

            Assert.False(wait.IsCompleted);

            lease.Dispose();

            Assert.True((await wait).IsAcquired);
        }
        /// <summary>
        /// Limits the number of concurrent messages consumed for the specified message type.
        /// </summary>
        /// <param name="configurator"></param>
        /// <param name="concurrentMessageLimit">The concurrent message limit for the message type</param>
        public static void UseConcurrentMessageLimit <TMessage>(this IPipeConfigurator <ConsumeContext <TMessage> > configurator, int concurrentMessageLimit)
            where TMessage : class
        {
            if (configurator == null)
            {
                throw new ArgumentNullException(nameof(configurator));
            }

            var limiter = new ConcurrencyLimiter(concurrentMessageLimit);

            var specification = new ConcurrencyLimitConsumePipeSpecification <TMessage>(limiter);

            configurator.AddPipeSpecification(specification);
        }
Exemplo n.º 15
0
        public override async Task IdleDurationUpdatesWhenIdle()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 1
            });

            Assert.NotNull(limiter.IdleDuration);
            var previousDuration = limiter.IdleDuration;
            await Task.Delay(15);

            Assert.True(previousDuration < limiter.IdleDuration);
        }
Exemplo n.º 16
0
        public override async Task WaitAsyncZero_WithoutAvailabilityWaitsForAvailability()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
            var lease   = await limiter.WaitAsync(1);

            Assert.True(lease.IsAcquired);

            var wait = limiter.WaitAsync(0);

            Assert.False(wait.IsCompleted);

            lease.Dispose();
            using var lease2 = await wait;
            Assert.True(lease2.IsAcquired);
        }
Exemplo n.º 17
0
        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));
        }
Exemplo n.º 18
0
        public override async Task FailsWhenQueuingMoreThanLimit_OldestFirst()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 1
            });

            using var lease = limiter.AttemptAcquire(1);
            var wait = limiter.AcquireAsync(1);

            var failedLease = await limiter.AcquireAsync(1);

            Assert.False(failedLease.IsAcquired);
        }
        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());
        }
Exemplo n.º 20
0
        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();
        }
Exemplo n.º 21
0
        public override async Task DropsOldestWhenQueuingMoreThanLimit_NewestFirst()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.NewestFirst, 1));
            var lease   = limiter.Acquire(1);
            var wait    = limiter.WaitAsync(1);

            Assert.False(wait.IsCompleted);

            var wait2  = limiter.WaitAsync(1);
            var lease1 = await wait;

            Assert.False(lease1.IsAcquired);
            Assert.False(wait2.IsCompleted);

            lease.Dispose();

            lease = await wait2;
            Assert.True(lease.IsAcquired);
        }
Exemplo n.º 22
0
        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());
        }
Exemplo n.º 23
0
        public override async Task CannotAcquireResourcesWithAcquireWithQueuedItemsIfOldestFirst()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(2, QueueProcessingOrder.OldestFirst, 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.False(lease2.IsAcquired);

            lease.Dispose();

            var lease1 = await wait1;

            Assert.True(lease1.IsAcquired);
        }
Exemplo n.º 24
0
        public override async Task QueueAvailableAfterQueueLimitHitAndResources_BecomeAvailable()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(1, QueueProcessingOrder.OldestFirst, 1));
            var lease   = limiter.Acquire(1);
            var wait    = limiter.WaitAsync(1);

            var failedLease = await limiter.WaitAsync(1);

            Assert.False(failedLease.IsAcquired);

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

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

            lease.Dispose();
            lease = await wait;
            Assert.True(lease.IsAcquired);
        }
Exemplo n.º 25
0
        public override async Task DropsRequestedLeaseIfPermitCountGreaterThanQueueLimitAndNoAvailability_NewestFirst()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions(2, QueueProcessingOrder.NewestFirst, 1));
            var lease   = limiter.Acquire(2);

            Assert.True(lease.IsAcquired);

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

            Assert.False(wait.IsCompleted);

            var lease1 = await limiter.WaitAsync(2);

            Assert.False(lease1.IsAcquired);

            lease.Dispose();
            var lease2 = await wait;

            Assert.True(lease2.IsAcquired);
        }
        /// <summary>
        /// Limits the number of concurrent messages consumed for the specified message type.
        /// </summary>
        /// <param name="configurator"></param>
        /// <param name="concurrentMessageLimit">The concurrent message limit for the message type</param>
        /// <param name="managementEndpointConfigurator">A management endpoint configurator to support runtime adjustment</param>
        /// <param name="id">An identifier for the concurrency limit to allow selective adjustment</param>
        public static void UseConcurrentMessageLimit <TMessage>(this IPipeConfigurator <ConsumeContext <TMessage> > configurator, int concurrentMessageLimit,
                                                                IManagementEndpointConfigurator managementEndpointConfigurator, string id = null)
            where TMessage : class
        {
            if (configurator == null)
            {
                throw new ArgumentNullException(nameof(configurator));
            }

            var limiter = new ConcurrencyLimiter(concurrentMessageLimit, id);

            var specification = new ConcurrencyLimitConsumePipeSpecification <TMessage>(limiter);

            configurator.AddPipeSpecification(specification);

            managementEndpointConfigurator.Instance(limiter, x =>
            {
                x.UseConcurrentMessageLimit(1);
                x.Message <SetConcurrencyLimit>(m => m.UseRetry(r => r.None()));
            });
        }
Exemplo n.º 27
0
        public override void GetStatisticsReturnsNewInstances()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 1,
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit           = 1
            });

            var stats = limiter.GetStatistics();

            Assert.Equal(1, stats.CurrentAvailablePermits);

            var lease = limiter.AttemptAcquire(1);

            var stats2 = limiter.GetStatistics();

            Assert.NotSame(stats, stats2);
            Assert.Equal(1, stats.CurrentAvailablePermits);
            Assert.Equal(0, stats2.CurrentAvailablePermits);
        }
Exemplo n.º 28
0
        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);
        }
Exemplo n.º 29
0
        public override async Task CanFillQueueWithNewestFirstAfterCancelingQueuedRequestWithAnotherQueuedRequest()
        {
            var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions
            {
                PermitLimit          = 2,
                QueueProcessingOrder = QueueProcessingOrder.NewestFirst,
                QueueLimit           = 2
            });
            var lease = limiter.AttemptAcquire(2);

            Assert.True(lease.IsAcquired);

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

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

            Assert.False(wait.IsCompleted);

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

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

            var wait3 = limiter.AcquireAsync(2);

            Assert.False(wait3.IsCompleted);

            // will be kicked by wait3 because we're using NewestFirst
            var lease2 = await wait2;

            Assert.False(lease2.IsAcquired);

            lease.Dispose();

            lease = await wait3;
            Assert.True(lease.IsAcquired);
        }
Exemplo n.º 30
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);
        }