-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Ensure taggers that compute frozen partial data eventually move to a 'correct' final state. #72878
Ensure taggers that compute frozen partial data eventually move to a 'correct' final state. #72878
Conversation
// amount of time waiting for all the compilation information to be built. For example, we can classify types | ||
// that we've parsed in other files, or partially loaded from metadata, even if we're still parsing/loading. | ||
// For cross language projects, this also produces semantic classifications more quickly as we do not have to | ||
// wait on skeletons to be built. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a move of this comment.
✅ Successfully linked to Azure Boards work item(s): |
EnqueueWork(highPriority, _dataSource.SupportsFrozenPartialSemantics); | ||
} | ||
|
||
private void EnqueueWork(bool highPriority, bool frozenPartialSemantics) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sharwell for eyes on thsi threading logic.
} | ||
else | ||
{ | ||
// We're asking for expensive tags, and this tagger supports frozen partial tags. Kick off the work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sharwell for extra attention here.
src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs
Outdated
Show resolved
Hide resolved
…ider.TagSource_ProduceTags.cs
…adi/roslyn into frozenPartialTagging
} | ||
|
||
protected override bool TagEquals(IClassificationTag tag1, IClassificationTag tag2) | ||
=> tag1.ClassificationType.Classification == tag2.ClassificationType.Classification; | ||
public async Task ProduceTagsAsync( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are just method moves from a utilities class far awqay. they were only called here (and referred to tagger types). so i just moved them all back over. they are otherwise unchanged.
/// cancel the expensive non-frozen tagging pass (which might be computing skeletons, SG docs, etc.), do the | ||
/// next cheap frozen-tagging-pass, and then push the expensive-nonfrozen-tagging-pass to the end again. | ||
/// </summary> | ||
private readonly CancellationSeries _nonFrozenComputationCancellationSeries = new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sharwell for eyes.
{ | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i felt like there could be a cleaner way of writing all this. but i couldn't figure it out :)
src/EditorFeatures/Core/ReferenceHighlighting/ReferenceHighlightingViewTaggerProvider.cs
Outdated
Show resolved
Hide resolved
…htingViewTaggerProvider.cs
…adi/roslyn into frozenPartialTagging
src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.cs
Outdated
Show resolved
Hide resolved
src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.TagSource_ProduceTags.cs
Show resolved
Hide resolved
src/EditorFeatures/Core/Tagging/AbstractAsynchronousTaggerProvider.cs
Outdated
Show resolved
Hide resolved
@@ -60,7 +60,7 @@ public static async Task<int[]> HandleRequestHelperAsync(Document document, Immu | |||
// If the full compilation is not yet available, we'll try getting a partial one. It may contain inaccurate | |||
// results but will speed up how quickly we can respond to the client's request. | |||
document = document.WithFrozenPartialSemantics(cancellationToken); | |||
options = options with { ForceFrozenPartialSemanticsForCrossProcessOperations = true }; | |||
options = options with { FrozenPartialSemantics = true }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 This seems like something we'll need to follow-up on.
…ider.cs Co-authored-by: Sam Harwell <[email protected]>
var highPriority = changes.Contains(true); | ||
return new ValueTask<VoidResult>(RecomputeTagsAsync(highPriority, cancellationToken)); | ||
var highPriority = changes.Contains(x => x.highPriority); | ||
var frozenPartialSemantics = changes.Contains(t => t.frozenPartialSemantics); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will add comment.
Fixes AB#2016199
Our previous approach for trying to make this work was buggy and was removed in #72384.
The issue there was that we would first compute tags, using frozen-partial-semantics. Then kick off work to get the compilation for the current project (in the host and oop), then kick off an event to compute tags again, again using frozen-partial-semantics. The issue with that was the presumption that if a compilation was successfully retrieved that the next frozen-partial snapshot would contain information from that. That's not how frozen-partial works though. As it is just a snapshot system, once we build that snapshot, it's fixed (and we want that, so that all the features talking to the same frozen snapshot get all the normal caching we want for solution snapshots). So the next frozen-partial-request could still just get the same results as the prior time, effectively making the call pointless.
The new approach changes things fundamentally at the tagger level in the following fashion:
This change now means that the last piece of work one of these taggers will always do is a request to tag on a real full snapshot, with full semantics. So if there are any inaccurate/incomplete tags from a prior frozen-tagging pass, they will be updated to now be correct.
Perf should also be fine as we always prefer to do work for the frozen-case first, continuously computing in a fast, but inaccurate, mode as long as events keep coming in. Only once there is a lull in processing will we be able to get to the full mode.