Skip to content

Remove BranchId from the workspace.#63578

Merged
CyrusNajmabadi merged 3 commits intodotnet:mainfrom
CyrusNajmabadi:branchId3
Aug 25, 2022
Merged

Remove BranchId from the workspace.#63578
CyrusNajmabadi merged 3 commits intodotnet:mainfrom
CyrusNajmabadi:branchId3

Conversation

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

Can choose to review this commit by commit, or just the end form.

The BranchId concept has always been somewhat suspect. It was a way of determining if the Solution instance you had was a Solution that had ever been teh .CurrentSolution of a workspace, or if you had a forked solution off of one of those solutions. Needing to know if you were one of these has never been clear as to why that's important. Roslyn operates in snapshots, and attempts to do so in a purely functional fashion. What does it matter if you were on a .CurrentSolution, or a fork of that, or a fork of that fork?

At one point we definitely used this when it came to persisting data. We didn't want analysis about a fork of a solution to overwrite data in our persistence service corresponding to the primary solution. However, that code went away ages ago when:

  1. we stopped storing diagnostic information in the persistence layer.
  2. we ensured that all persisted data is stored with a checksum.

At that point, there was no concern about overwriting data with something invalid.

This PR gets rid of hte BranchId concept entirely and fixes up any remaining stragglers to get off of it.

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner August 24, 2022 19:56
@ghost ghost added the Area-IDE label Aug 24, 2022
{
var solution = _workspace.CurrentSolution;
if (solution.BranchId != _workspace.PrimaryBranchId)
return;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

totally unnecessary. we are always accessing _workspace.CurrentSolution above. So this solution was always the primary-branch solution.

private readonly ConditionalWeakTable<Solution, Solution> _designTimeToCompileTimeSolution = new();
#else
private ConditionalWeakTable<Solution, Solution> _designTimeToCompileTimeSolution = new();
#endif
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

.net core has ConditionalWeakTable.Clear(). Standard does not. So we simulate it by overwriting the field.

/// Cached compile time solution for a forked branch. This is used primarily by LSP cases where
/// we fork the workspace solution and request diagnostics for the forked solution.
/// </summary>
private (int DesignTimeSolutionVersion, BranchId DesignTimeSolutionBranch, Solution CompileTimeSolution)? _forkedBranchCompileTimeCache;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@dibarbet i believe this has the semantics from before. Previously we keyed basd on Version+BranchId. But these change every time you get a new solution. So the only time these woudl match would be if you passed in teh exact same (reference-equals) Solution instance from before. So we can get the same behavior by using a CWT keyed off Solution instances.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The idea here being that as soon as no one is using the solution we can get rid of the design time solution. Makes sense to me.


// We only track performance from primary branch. All forked branch we don't care such as preview.
_performanceTracker = project.IsFromPrimaryBranch() ? project.Solution.Services.GetService<IPerformanceTrackerService>() : null;
_performanceTracker = project.Solution.Services.GetRequiredService<IPerformanceTrackerService>();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i don't see the value that in this. Why would it not matter what the performance was getting diagnostics in a preview workspace?

{
CheckNoChanges(oldSolution, newSolution);
return true;
}
Copy link
Copy Markdown
Contributor Author

@CyrusNajmabadi CyrusNajmabadi Aug 24, 2022

Choose a reason for hiding this comment

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

also not certain what teh value here is. If someone asks us to apply changes, we can simply walk through and figure out waht the changes were. This was a fast-bail-out for a case that seems like the unlikely one (e.g. when does someone ask to apply the same solution over the exisitng solution)?

we could choose to still haev a check like if (oldSolution == newSolution). but i question if htat has any value whatsoever given that newSolution.GetChanges(oldSolution) will just return an empty set of changes.

#if NETCOREAPP
_designTimeToCompileTimeSolution.Clear();
#else
_designTimeToCompileTimeSolution = new();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

note: doing the above seems unnecessary. as a CWT, they should naturally release their resources when they are no longer referenced anywhere.

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor Author

@dibarbet @jasonmalinowski ptal.

/// Cached compile time solution for a forked branch. This is used primarily by LSP cases where
/// we fork the workspace solution and request diagnostics for the forked solution.
/// </summary>
private (int DesignTimeSolutionVersion, BranchId DesignTimeSolutionBranch, Solution CompileTimeSolution)? _forkedBranchCompileTimeCache;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The idea here being that as soon as no one is using the solution we can get rid of the design time solution. Makes sense to me.

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.

2 participants