public async Task WhenWorkIsAddedAgainWhenPreviousIsAnalysing_ThenDontWaitAnotherOneToGetReady() { var now = DateTime.UtcNow; var loggerFactory = new LoggerFactory(); var queue = new AnalyzerWorkQueue(loggerFactory, utcNow: () => now); var document = CreateTestDocumentId(); queue.PutWork(document); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(); var waitingCall = Task.Run(async() => await queue.WaitForResultsAsync(work)); await Task.Delay(50); // User updates code -> document is queued again during period when theres already api call waiting // to continue. queue.PutWork(document); // First iteration of work is done. queue.MarkWorkAsCompleteForDocumentId(document); // Waiting call continues because it's iteration of work is done, even when theres next // already waiting. await waitingCall; Assert.True(waitingCall.IsCompleted); Assert.Empty(loggerFactory.Logger.RecordedMessages); }
public async Task WhenWorkIsAddedAgainWhenPreviousIsAnalysing_ThenDontWaitAnotherOneToGetReady() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 10 * 1000); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(AnalyzerWorkType.Foreground); var waitingCall = Task.Run(async() => await queue.WaitForegroundWorkComplete()); await Task.Delay(50); // User updates code -> document is queued again during period when theres already api call waiting // to continue. queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground); // First iteration of work is done. queue.WorkComplete(AnalyzerWorkType.Foreground); // Waiting call continues because its iteration of work is done, even when theres next // already waiting. await waitingCall; Assert.True(waitingCall.IsCompleted); }
public async Task WhenMultipleThreadsAreConsumingAnalyzerWorkerQueueItWorksAsExpected() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 1000); var parallelQueues = Enumerable.Range(0, 10) .Select(_ => Task.Run(() => { var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(AnalyzerWorkType.Foreground); var pendingTask = queue.WaitForegroundWorkComplete(); queue.WaitForegroundWorkComplete(); pendingTask.Wait(TimeSpan.FromMilliseconds(300)); })) .ToArray(); await Task.WhenAll(parallelQueues); Assert.Empty(queue.TakeWork(AnalyzerWorkType.Foreground)); }
public void WhenSameItemIsAddedMultipleTimesInRowThenThrottleItemAsOne(AnalyzerWorkType workType) { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 10 * 1000); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, workType); queue.PutWork(new[] { document }, workType); queue.PutWork(new[] { document }, workType); Assert.Empty(queue.TakeWork(workType)); now = PassOverThrotlingPeriod(now); Assert.Contains(document, queue.TakeWork(workType)); Assert.Empty(queue.TakeWork(workType)); }
public void WhenSameItemIsAddedMultipleTimesInRowThenThrottleItemAsOne() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now); var document = CreateTestDocumentId(); queue.PutWork(document); queue.PutWork(document); queue.PutWork(document); Assert.Empty(queue.TakeWork()); now = PassOverThrotlingPeriod(now); Assert.Contains(document, queue.TakeWork()); Assert.Empty(queue.TakeWork()); }
public void WhenItemsAreAddedButThrotlingIsntOverNoWorkShouldBeReturned(AnalyzerWorkType workType) { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 10 * 1000); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, workType); Assert.Empty(queue.TakeWork(workType)); }
public void WhenBackgroundWorkIsAdded_DontWaitIt() { var queue = new AnalyzerWorkQueue(new LoggerFactory(), timeoutForPendingWorkMs: 10 * 1000); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, AnalyzerWorkType.Background); Assert.True(queue.WaitForegroundWorkComplete().IsCompleted); }
public void WhenItemsAreAddedButThrotlingIsntOverNoWorkShouldBeReturned() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now); var document = CreateTestDocumentId(); queue.PutWork(document); Assert.Empty(queue.TakeWork()); }
public void WhenWorksIsAddedToQueueThenTheyWillBeReturned(AnalyzerWorkType workType) { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 10 * 1000); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, workType); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(workType); Assert.Contains(document, work); Assert.Empty(queue.TakeWork(workType)); }
public void WhenSingleFileIsPromoted_ThenPromoteItFromBackgroundQueueToForeground() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 10 * 1000); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, AnalyzerWorkType.Background); queue.TryPromote(document); now = PassOverThrotlingPeriod(now); Assert.NotEmpty(queue.TakeWork(AnalyzerWorkType.Foreground)); }
public void WhenWorksIsAddedToQueueThenTheyWillBeReturned() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now); var document = CreateTestDocumentId(); queue.PutWork(document); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(); Assert.Contains(document, work); Assert.Empty(queue.TakeWork()); }
public void WhenWorkIsWaitedButTimeoutForWaitIsExceededAllowContinue() { var now = DateTime.UtcNow; var loggerFactory = new LoggerFactory(); var queue = new AnalyzerWorkQueue(loggerFactory, utcNow: () => now, timeoutForPendingWorkMs: 20); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(AnalyzerWorkType.Foreground); var pendingTask = queue.WaitForegroundWorkComplete(); var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(5)); pendingTask.Wait(cts.Token); Assert.True(pendingTask.IsCompleted); Assert.Contains("Timeout before work got ready", loggerFactory.Logger.RecordedMessages.Single()); }
public void WhenForegroundWorkIsUnderAnalysisOutFromQueueThenWaitUntilNextIterationOfItIsReady() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 500); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, AnalyzerWorkType.Foreground); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(AnalyzerWorkType.Foreground); var pendingTask = queue.WaitForegroundWorkComplete(); pendingTask.Wait(TimeSpan.FromMilliseconds(50)); Assert.False(pendingTask.IsCompleted); queue.WorkComplete(AnalyzerWorkType.Foreground); pendingTask.Wait(TimeSpan.FromMilliseconds(50)); Assert.True(pendingTask.IsCompleted); }
public void WhenFileIsProcessingInBackgroundQueue_ThenPromoteItAsForeground() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new TestLoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 10 * 1000); var document = CreateTestDocumentId(); queue.PutWork(new[] { document }, AnalyzerWorkType.Background); now = PassOverThrotlingPeriod(now); var activeWork = queue.TakeWork(AnalyzerWorkType.Background); queue.QueueDocumentForeground(document); now = PassOverThrotlingPeriod(now); var foregroundWork = queue.TakeWork(AnalyzerWorkType.Foreground); Assert.NotEmpty(foregroundWork); Assert.NotEmpty(activeWork); }
public void WhenWorkIsAddedThenWaitNextIterationOfItReady() { var now = DateTime.UtcNow; var queue = new AnalyzerWorkQueue(new LoggerFactory(), utcNow: () => now, timeoutForPendingWorkMs: 500); var document = CreateTestDocumentId(); queue.PutWork(document); var pendingTask = queue.WaitForResultsAsync(new [] { document }.ToImmutableArray()); pendingTask.Wait(TimeSpan.FromMilliseconds(50)); Assert.False(pendingTask.IsCompleted); now = PassOverThrotlingPeriod(now); var work = queue.TakeWork(); queue.MarkWorkAsCompleteForDocumentId(document); pendingTask.Wait(TimeSpan.FromMilliseconds(50)); Assert.True(pendingTask.IsCompleted); }
private void QueueForAnalysis(ImmutableArray <DocumentId> documentIds, AnalyzerWorkType workType) { _workQueue.PutWork(documentIds, workType); }