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

[LSP] Fix race in document change tracker when used in non-mutating requests. #57317

Merged
merged 7 commits into from
Oct 26, 2021

Conversation

dibarbet
Copy link
Member

Previously, the NonMutatingDocumentChangeTracker had a reference to the mutating tracker to get tracked documents. However the mutating tracker was definitely not threadsafe and would not accurately reflect the tracked documents based on the request order in the queue (later lsp open requests would be seen as 'tracked' by requests prior to the open since the handler was just looking at current state).

This modifies the change tracking a bit. Now LSpWorkspaceManager implements IDocumentChangeTracker. Each request context then gets a snapshot of the LSP tracked text when the request is de-queued (serially).

Also addresses a couple small bits of feedback from @jasonmalinowski on the PR.

Resolves #57276

…cked documents in a non-mutating handler would change depending on text sync requests that were ordered after
@dibarbet dibarbet added Area-IDE LSP issues related to the roslyn language server protocol implementation labels Oct 22, 2021
@dibarbet dibarbet requested a review from a team as a code owner October 22, 2021 01:53
@@ -126,10 +136,10 @@ private void OnWorkspaceRegistered(object? sender, LspWorkspaceRegisteredEventAr
private void OnWorkspaceChanged(object? sender, WorkspaceChangeEventArgs e)
{
var workspace = e.NewSolution.Workspace;
if (e.Kind is WorkspaceChangeKind.DocumentChanged or WorkspaceChangeKind.AdditionalDocumentChanged or WorkspaceChangeKind.AnalyzerConfigDocumentChanged)
Copy link
Member

Choose a reason for hiding this comment

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

why this cahnge?

Copy link
Member Author

Choose a reason for hiding this comment

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

This was pointed about by Jason on the last PR. I removed them for a couple reasons

  1. Accessing additional / analyzer docs requires a different API than GetRequiredDocument, so the old code would have thrown on a change to them.
  2. We currently don't hear about changes to additional/analyzer documents via LSP, so they will always be workspace changes.

At some point if we want to support LSP for those kinds of documents, we'll have to do more changes than the ones here.

Copy link
Member

Choose a reason for hiding this comment

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

sgtm.

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

the race condition pointi made needs an answer. either it needs a fix, or it needs an explanation for why i'm wrong :)

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

nits can be ignored. but there still is one read of the field that is done inconsistently. it needs to be doc'ed, or made consistent, or other pure reads need to follow that pattern.

imo, teh simplest and most consistent is to be intentional about the lock everywhere to ensure absolutely clear exclusive semantics over it in all circumstances.

_workspaceToLspSolution[workspace] = null;
}

static bool IsDocumentTrackedByLsp(DocumentId changedDocumentId, Solution newWorkspaceSolution, IDocumentChangeTracker documentChangeTracker)
bool IsDocumentTrackedByLsp(DocumentId changedDocumentId, Solution newWorkspaceSolution, ImmutableDictionary<Uri, SourceText> trackedDocuments)
Copy link
Member

Choose a reason for hiding this comment

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

nit. called in one place. pretty trivial. could inline.

@dibarbet dibarbet changed the base branch from main to release/dev17.1 October 25, 2021 23:25
@dibarbet
Copy link
Member Author

@jinujoseph for m2 approval - a followup with a few fixes for #57140 which should go into p1 since the previous PR went into p1

Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

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

@dibarbet Nice changes, I like it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Approved to merge Area-IDE LSP issues related to the roslyn language server protocol implementation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[LSP] Race in LSP document tracker when accessing tracked documents from non-mutating handlers
4 participants