public async Task ConcurrencyLimitIsRespected(SemaphoreOrder order) { var cycles = 4; for (var cycle = 0; cycle < cycles; cycle++) { var concurrencyLimit = 10; var semaphore = new OrderedSemaphore(concurrencyLimit: concurrencyLimit, order, Context); // Use up the semaphore for (var i = 0; i < concurrencyLimit; i++) { (await semaphore.WaitAsync(Timeout.InfiniteTimeSpan, CancellationToken.None)).Should().BeTrue(); } // Any more should not be immediatelly successful var task = semaphore.WaitAsync(Timeout.InfiniteTimeSpan, CancellationToken.None); await Task.Delay(TimeSpan.FromMilliseconds(1)); task.IsCompleted.Should().BeFalse(); // Releasing at least one space should free up a space. semaphore.Release(); (await task).Should().BeTrue(); // Clear the semaphore. for (var i = 0; i < concurrencyLimit; i++) { semaphore.Release(); } } }
public DefaultCopyScheduler(DefaultCopySchedulerConfiguration configuration, Context tracingContext) { _configuration = configuration; _outboundPullGate = new OrderedSemaphore( configuration.OutboundPullConfiguration.MaximumConcurrency, configuration.OutboundPullConfiguration.SemaphoreOrder, tracingContext); _outboundPushGate = new OrderedSemaphore( configuration.OutboundPushConfiguration.MaximumConcurrency, configuration.OutboundPushConfiguration.SemaphoreOrder, tracingContext); }
internal async Task AlreadyCancelledTokenIsRespected(SemaphoreOrder order) { var concurrencyLimit = 10; var semaphore = new OrderedSemaphore(concurrencyLimit: concurrencyLimit, order, Context); // Fill out the semaphore var tasks = Enumerable.Range(0, concurrencyLimit).Select(async num => await semaphore.WaitAsync(Timeout.InfiniteTimeSpan, CancellationToken.None)); (await Task.WhenAll(tasks)).Should().AllBeEquivalentTo(true); // Queue tasks which should be blocked by other running tasks var cts = new CancellationTokenSource(); cts.Cancel(); var blockedTasks = Enumerable.Range(0, concurrencyLimit).Select(async num => await semaphore.WaitAsync(Timeout.InfiniteTimeSpan, cts.Token)); blockedTasks.Select(t => Assert.ThrowsAsync <TaskCanceledException>(() => t)).ToArray(); }
public async Task CancellationTokenTimeoutIsDetected(SemaphoreOrder order) { var concurrencyLimit = 10; var semaphore = new OrderedSemaphore(concurrencyLimit: concurrencyLimit, order, Context); // Fill out the semaphore var tasks = Enumerable.Range(0, concurrencyLimit).Select(async num => await semaphore.WaitAsync(Timeout.InfiniteTimeSpan, CancellationToken.None)); (await Task.WhenAll(tasks)).Should().AllBeEquivalentTo(true); // Queue tasks which should be blocked by other running tasks var cts = new CancellationTokenSource(delay: TimeSpan.FromMilliseconds(100)); var blockedTasks = Enumerable.Range(0, concurrencyLimit).Select(async num => await semaphore.WaitAsync(Timeout.InfiniteTimeSpan, cts.Token)); await Task.Delay(TimeSpan.FromMilliseconds(1)); // Should all be blocked blockedTasks.Select(t => t.IsCompleted.Should().BeFalse()).ToArray(); blockedTasks.Select(t => Assert.ThrowsAsync <TaskCanceledException>(() => t)).ToArray(); }
public DistributedContentCopier( DistributedContentStoreSettings settings, IAbsFileSystem fileSystem, IRemoteFileCopier fileCopier, IContentCommunicationManager copyRequester, IClock clock, ILogger logger) { Contract.Requires(settings != null); Contract.Requires(settings.ParallelHashingFileSizeBoundary >= -1); _settings = settings; _remoteFileCopier = fileCopier; _copyRequester = copyRequester; FileSystem = fileSystem; _clock = clock; _ioGate = new OrderedSemaphore(_settings.MaxConcurrentCopyOperations, _settings.OrderForCopies, new Context(logger)); _proactiveCopyIoGate = new OrderedSemaphore(_settings.MaxConcurrentProactiveCopyOperations, _settings.OrderForProactiveCopies, new Context(logger)); _retryIntervals = settings.RetryIntervalForCopies; _maxRetryCount = settings.MaxRetryCount; _ioGateTimeoutForProactiveCopies = settings.ProactiveCopyIOGateTimeout; }
public async Task OrderIsRespected(SemaphoreOrder order) { var semaphore = new OrderedSemaphore(concurrencyLimit: 1, order, Context); var amountTasks = 10; var results = new List <int>(); // Block to make sure that we have time to create all tasks before they start executing; otherwise LIFO will be flaky. await semaphore.WaitAsync(Timeout.InfiniteTimeSpan, CancellationToken.None); var tasks = Enumerable.Range(0, amountTasks).Select(async num => { (await semaphore.WaitAsync(Timeout.InfiniteTimeSpan, CancellationToken.None)).Should().BeTrue(); results.Add(num); semaphore.Release(); }).ToArray(); // Tasks should be blocked. results.Count.Should().Be(0); // Unblock tasks semaphore.Release(); // Wait for tasks to complete and validate results. await Task.WhenAll(tasks); results.Count.Should().Be(amountTasks); for (var i = 0; i < results.Count; i++) { var expected = order == SemaphoreOrder.FIFO ? i : amountTasks - i - 1; results[i].Should().Be(expected); } }
public async Task LongTimeoutIsRespected(SemaphoreOrder order) { var semaphore = new OrderedSemaphore(concurrencyLimit: 0, order, Context); (await semaphore.WaitAsync(timeout: TimeSpan.FromMilliseconds(10), CancellationToken.None)).Should().BeFalse(); }