-
Notifications
You must be signed in to change notification settings - Fork 416
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
Decouple FixAll from the workspace #1962
Conversation
Today, the RunFixAllInCodeActionService is tightly coupled to the current workspace, applying its changes to the workspace as it processes the request and counting on the updates from doing so to invalidate diagnostic caches. While this does work, it's has 2 major downsides: 1. It's a race condition waiting to happen, where the propagation of the changed documents invalidating the diagnostic provider's caches races with the next fix all operation attempting to get the diagnostics it needs to fix. 2. It has bad interations with the buffer updater from clients. The service returns the needed changes to clients, who then apply the changes. The client will then see that changes have been applied, and send them back to the server. The server's workspace has already been updated with these changes, so it ends up double applying the changes, leaving the server's workspace in a bad state with garbage in many files. This commit breaks the dependency of the FixAll service on the current workspace. We now have the fixes occur on top of the previous fix's changed solution. At the end, if the client requested the changes be applied on the workspace side, then we apply the changes to the workspace at that point. In order for this work, I had to modify the diagnostic workers a bit to add an option to force a document to be analyzed, skipping the cache entirely. This is necessary because the cache is only invalidated on document add/remove/change in the workspace itself. The documents we work on linearly in the fix all provider do not get added/changed/removed in the workspace, so we need to analyze them again, right then and there. To support this, the AnalyzerWorkQueue is now based on documents, not document ids, though the caches in the workers are still based on ids.
d88cbb9
to
8aa8252
Compare
@filipw I'm not sure if any of these test failures could be related to this change. Can you advise? |
no, all three separate failures are "known" to be flaky already... let's see the retry |
src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs
Outdated
Show resolved
Hide resolved
src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs
Outdated
Show resolved
Hide resolved
src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs
Outdated
Show resolved
Hide resolved
src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/BaseCodeActionService.cs
Show resolved
Hide resolved
src/OmniSharp.Roslyn.CSharp/Services/Refactoring/V2/BaseCodeActionService.cs
Outdated
Show resolved
Hide resolved
src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs
Outdated
Show resolved
Hide resolved
src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorkerWithAnalyzers.cs
Outdated
Show resolved
Hide resolved
…n DocumentId->Diagnostics. This is done via a ConditionalWeakTable to ensure we don't root Documents and prevent garbage collection.
@david-driscoll I believe I've addressed your feedback. |
src/OmniSharp.Roslyn.CSharp/Services/Refactoring/RunFixAllCodeActionService.cs
Show resolved
Hide resolved
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.
@david-driscoll Would you like to give this PR your blessing? =) |
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.
* Readd incremental changes. * React to OmniSharp/omnisharp-roslyn#1962
Today, the RunFixAllInCodeActionService is tightly coupled to the current workspace, applying its changes to the workspace as it processes the request and counting on the updates from doing so to invalidate diagnostic caches. While this does work, it's has 2 major downsides:
This commit breaks the dependency of the FixAll service on the current workspace. We now have the fixes occur on top of the previous fix's changed solution. At the end, if the client requested the changes be applied on the workspace side, then we apply the changes to the workspace at that point. In order for this work, I had to modify the diagnostic workers a bit to add an option to force a document to be analyzed, skipping the cache entirely. This is necessary because the cache is only invalidated on document add/remove/change in the workspace itself. The documents we work on linearly in the fix all provider do not get added/changed/removed in the workspace, so we need to analyze them again, right then and there. To support this, the AnalyzerWorkQueue is now based on documents, not document ids, though the caches in the workers are still based on ids.
In the process of doing this PR, I also fixed #1960.