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); }
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); }
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 _)); }
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)); }
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); }
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(); }
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); }
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); }
public override void GetStatisticsThrowsAfterDispose() { var limiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions { PermitLimit = 100, QueueProcessingOrder = QueueProcessingOrder.OldestFirst, QueueLimit = 50 }); limiter.Dispose(); Assert.Throws <ObjectDisposedException>(limiter.GetStatistics); }
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); }
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); }
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); } }
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); }
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); }
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); }
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 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()); }
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 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); }
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 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); }
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); }
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())); }); }
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); }
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); }
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); }
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); }