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

Fix workspace pull diagnostics #66886

Merged
merged 4 commits into from
Mar 2, 2023

Conversation

dibarbet
Copy link
Member

@dibarbet dibarbet commented Feb 14, 2023

Update our public spec implementation of workspace pull diagnostics to hold the request open when nothing changes to avoid the client spamming the server with requests.

@dibarbet dibarbet force-pushed the workspace_diagnostics_poll branch 3 times, most recently from 3a80693 to 1d8f137 Compare February 14, 2023 21:41
// have happened while this request was running or might happen after.
// Only if there are no changes between now and the next request completing, we will hold the connection open while we poll for changes.
_lspChanged = false;
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could just use an InterlockedExchange here.

Comment on lines 182 to 183
await Task.Delay(TimeSpan.FromMilliseconds(100))
.ContinueWith(async (_) => await WaitForChangesAsync().ConfigureAwait(false), TaskScheduler.Default).ConfigureAwait(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
await Task.Delay(TimeSpan.FromMilliseconds(100))
.ContinueWith(async (_) => await WaitForChangesAsync().ConfigureAwait(false), TaskScheduler.Default).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromMilliseconds(100)).ConfigureAwait(false);
await WaitForChangesAsync().ConfigureAwait(false);

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, i know why i don't like this. just make this an actual loop in code, instead of a function that calls itself :)

@dibarbet dibarbet force-pushed the workspace_diagnostics_poll branch 2 times, most recently from 10dea9d to d9beb4d Compare February 14, 2023 22:49
@dibarbet dibarbet force-pushed the workspace_diagnostics_poll branch from d9beb4d to 2d88502 Compare February 16, 2023 02:00
@dibarbet dibarbet marked this pull request as ready for review February 16, 2023 02:01
@dibarbet dibarbet requested a review from a team as a code owner February 16, 2023 02:01
@sharwell sharwell marked this pull request as draft February 16, 2023 02:51
Interlocked.Exchange(ref _lspChanged, 1);
}

protected override async Task WaitForChangesAsync(RequestContext context)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Consider adding another way to exit this (some sort of shutdown cancellation token)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 ... yes this should absolutely use the cancellation token passed in by the queue. that'll take care of either request cancellation / shutdown. fixed!

@dibarbet dibarbet changed the title WIP - fix workspace pull diagnostics Fix workspace pull diagnostics Feb 16, 2023
@dibarbet dibarbet marked this pull request as ready for review February 16, 2023 18:14
await testLspServer.WaitForDiagnosticsAsync();

BufferedProgress<WorkspaceDiagnosticPartialReport>? progress = useProgress ? BufferedProgress.Create<WorkspaceDiagnosticPartialReport>(null) : null;
var diagnosticsTask = testLspServer.ExecuteRequestAsync<WorkspaceDiagnosticParams, WorkspaceDiagnosticReport?>(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hide whitespace changes for this

@@ -21,14 +22,32 @@ namespace Microsoft.CodeAnalysis.LanguageServer.Handler.Diagnostics.Public;
using WorkspaceDiagnosticPartialReport = SumType<WorkspaceDiagnosticReport, WorkspaceDiagnosticReportPartialResult>;

[Method(Methods.WorkspaceDiagnosticName)]
internal class PublicWorkspacePullDiagnosticsHandler : AbstractPullDiagnosticHandler<WorkspaceDiagnosticParams, WorkspaceDiagnosticPartialReport, WorkspaceDiagnosticReport?>
internal class PublicWorkspacePullDiagnosticsHandler : AbstractPullDiagnosticHandler<WorkspaceDiagnosticParams, WorkspaceDiagnosticPartialReport, WorkspaceDiagnosticReport?>, IDisposable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious. why only do this in the public workspace pull side? is the non-public side not affected?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the client polls in the other version.

{
_workspaceManager.LspTextChanged -= OnLspTextChanged;
_workspaceRegistrationService.LspSolutionChanged -= OnLspSolutionChanged;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please put Dispose right after constructor? i find it much easier to reason about that way. :)

@@ -87,6 +87,8 @@ internal class LspWorkspaceManager : IDocumentChangeTracker, ILspService
_lspWorkspaceRegistrationService = lspWorkspaceRegistrationService;
}

public EventHandler<EventArgs>? LspTextChanged;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc.

_workspaceRegistrationService.LspSolutionChanged += OnLspSolutionChanged;

_workspaceManager = workspaceManager;
_workspaceManager.LspTextChanged += OnLspTextChanged;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why do we listen for text-changed if we're alrady listening to solution changed? the former seems unnecessary. would that help simplify?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LspSolutionChange means the backing workspace solution changed, it doesn't include changes for open documents (because we don't create a solution on LSP text changes, only when a request needing a solution comes in).

@dibarbet dibarbet merged commit 81404ba into dotnet:main Mar 2, 2023
@dibarbet dibarbet deleted the workspace_diagnostics_poll branch March 2, 2023 22:58
@ghost ghost added this to the Next milestone Mar 2, 2023
@allisonchou allisonchou modified the milestones: Next, 17.6 P3 Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants