Skip to content

Delete the lazy caching of GetLatestProjectVersion()#41412

Merged
jasonmalinowski merged 1 commit intodotnet:release/dev16.5from
jasonmalinowski:simplify-latestprojectversion
Feb 6, 2020
Merged

Delete the lazy caching of GetLatestProjectVersion()#41412
jasonmalinowski merged 1 commit intodotnet:release/dev16.5from
jasonmalinowski:simplify-latestprojectversion

Conversation

@jasonmalinowski
Copy link
Copy Markdown
Member

Solution.GetLatestProjectVersion() returns the highest project version of any of the Projects in the Solution. This is lazily computed, but the lazy computation has a fatal flaw. It's implemented with a Lazy, and if a Solution is changed and no project was changed (say, you only modified a document's text), the existing Lazy is reused. This causes us to root an older SolutionState or ProjectState until somebody were to call GetLatestProjectVersion() and cause the Lazy to be evaluated.

Except...that would never happen. It turns out that nothing calls GetLatestProjectVersion() in Visual Studio anywhere that I can find. The only call is in one unit test that calls it and then ignores the result. Thus, we'd simply leak the SolutionState/ProjectState until some code ran that knew it could explicitly state the value instead of reuse the existing Lazy.

Looking through history, it appears that this used to be used more regularly as a part of an older implementation of the ProjectDependencyGraph, but that was removed in abd7654.

Since nobody calls this, and the actual computation (just looping through all projects to find the newest stamp) is fairly trivial, I'm just going to delete all the lazy handling and just inline the computation. In the unlikely case that this ever becomes a hot path, we can revisit the laziness at that time.

@jasonmalinowski jasonmalinowski requested a review from a team as a code owner February 5, 2020 01:00
@jasonmalinowski jasonmalinowski changed the base branch from master to release/dev16.5 February 5, 2020 01:00
Solution.GetLatestProjectVersion() returns the highest project version
of any of the Projects in the Solution. This is lazily computed, but
the lazy computation has a fatal flaw. It's implemented with a
Lazy<VersionStamp>, and if a Solution is changed and no project was
changed (say, you only modified a document's text), the existing
Lazy<VersionStamp> is reused. This causes us to root an older
SolutionState or ProjectState until somebody were to call
GetLatestProjectVersion() and cause the Lazy<VersionStamp> to be
evaluated.

Except...that would never happen. It turns out that nothing calls
GetLatestProjectVersion() in Visual Studio anywhere that I can find.
The only call is in one unit test that calls it and then ignores the
result. Thus, we'd simply leak the SolutionState/ProjectState until
some code ran that knew it could explicitly state the value instead of
reuse the existing Lazy<VersionStamp>.

Looking through history, it appears that this used to be used more
regularly as a part of an older implementation of the
ProjectDependencyGraph, but that was removed in
abd7654.

Since nobody calls this, and the actual computation (just looping
through all projects to find the newest stamp) is fairly trivial, I'm
just going to delete all the lazy handling and just inline the
computation. In the unlikely case that this ever becomes a hot path,
we can revisit the laziness at that time.
@jasonmalinowski jasonmalinowski force-pushed the simplify-latestprojectversion branch from 47f4089 to 252064f Compare February 5, 2020 01:02
@jasonmalinowski jasonmalinowski self-assigned this Feb 5, 2020
Copy link
Copy Markdown
Member

@JoeRobich JoeRobich left a comment

Choose a reason for hiding this comment

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

LGTM

Comment thread src/Workspaces/Core/Portable/Workspace/Solution/SolutionState.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants