Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async diagnostics analyzer work queue #2351

Merged
merged 22 commits into from
Sep 25, 2023
Merged
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Unit test fixes
neoGeneva committed Mar 4, 2022
commit a7deebabda95544183eb8b6f45140614e74ef050
Original file line number Diff line number Diff line change
@@ -284,15 +284,21 @@ public void WorkComplete(DocumentId documentId, CancellationToken cancellationTo
if (cancellationTokenSources.Count == 0)
_active.Remove(documentId);

foreach (var waiter in _waiters.ToList())
var isReenqueued = cancellationToken.IsCancellationRequested
&& (_hash.Contains(documentId) || _active.ContainsKey(documentId));

if (!isReenqueued)
{
if (waiter.DocumentIds.Remove(documentId) && waiter.DocumentIds.Count == 0)
foreach (var waiter in _waiters.ToList())
{
waiter.TaskCompletionSource.SetResult(null);
if (waiter.DocumentIds.Remove(documentId) && waiter.DocumentIds.Count == 0)
{
waiter.TaskCompletionSource.SetResult(null);

_waiters.Remove(waiter);
_waiters.Remove(waiter);
}
}
}
}
}
}

Original file line number Diff line number Diff line change
@@ -136,7 +136,34 @@ public async Task WhenMultipleThreadsAreConsumingAnalyzerWorkerQueueItWorksAsExp
}

[Fact]
public async Task WhenWorkIsAddedAgainWhenPreviousIsAnalysing_ThenDontWaitAnotherOneToGetReady()
public async Task WheNewnWorkIsAddedAgainWhenPreviousIsAnalysing_ThenDontWaitAnotherOneToGetReady()
JoeRobich marked this conversation as resolved.
Show resolved Hide resolved
{
var queue = new AsyncAnalyzerWorkQueue(new LoggerFactory());
var document1 = CreateTestDocumentId();
var document2 = CreateTestDocumentId();

queue.PutWork(new[] { document1 }, AnalyzerWorkType.Foreground);

var work = await queue.TakeWorkAsync();
var waitingCall = Task.Run(async () => await queue.WaitForegroundWorkCompleteWithTimeout(10 * 1000));
await Task.Delay(50);

// User updates code -> document is queued again during period when theres already api call waiting
// to continue.
queue.PutWork(new[] { document2 }, AnalyzerWorkType.Foreground);

// First iteration of work is done.
queue.WorkComplete(work);

// Waiting call continues because its iteration of work is done, even when theres next
// already waiting.
waitingCall.Wait(50);

Assert.True(waitingCall.IsCompleted);
}

[Fact]
public async Task WhenWorkIsAddedAgainWhenPreviousIsAnalysing_ThenContinueWaiting()
{
var queue = new AsyncAnalyzerWorkQueue(new LoggerFactory());
var document = CreateTestDocumentId();
@@ -158,7 +185,7 @@ public async Task WhenWorkIsAddedAgainWhenPreviousIsAnalysing_ThenDontWaitAnothe
// already waiting.
waitingCall.Wait(50);

Assert.True(waitingCall.IsCompleted);
Assert.False(waitingCall.IsCompleted);
}

[Fact]