Skip to content

Conversation

@CyrusNajmabadi
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi commented Feb 14, 2024

Followup to #72090

The core idea here relates to how we get a frozen partial solution snapshot that contains a document within it.

The prior way of doing this was to do the freezing step, passing the docstate inwards for the document we wanted in the final frozen solution. This required deep knowledge within CompilationTrackers for how to freeze, but also contain a document.

The new logic inverts this idea. Now, we simply freeze the solution. Then we take that frozen solution, and we ensure that it contains the doc-state for the document in question (adding or updating as appropriate). This allows us to reuse the existing outer helpers for this purpose, keeping compilation trackers simpler.

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner February 14, 2024 19:54
@ghost ghost added Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead labels Feb 14, 2024
// to contribute any changes that would affect which types we think are designable), and we want to be
// very fast to update the ui as a user types.
var frozenSolution = await solution.WithFrozenPartialCompilationsAsync(cancellationToken).ConfigureAwait(false);
var frozenSolution = solution.WithFrozenPartialCompilations(cancellationToken);
Copy link
Member Author

Choose a reason for hiding this comment

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

became synchronous as this can be done entirely without async work.

Copy link
Member

Choose a reason for hiding this comment

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

It looks like it was never async before, other than because of us calling the AsyncLazy GetValueAsync? I wonder if it's good/bad for us to be using AsyncLazy too for non-async cases when we want regular Lazy but also have a bit friendlier of a cancellation story.

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah. it's def interesting. i don't personally mind it :)

{
var state = this.ReadState();

// If we're already finalized then just return what we have, and with the frozen bit flipped so that
Copy link
Member Author

Choose a reason for hiding this comment

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

all this work got effectively inlined into this method.

Copy link
Member Author

Choose a reason for hiding this comment

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

the diff is awful. i recommend not looking at it inlined.

Copy link
Member Author

Choose a reason for hiding this comment

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

ok. because the diff was so awful, i moved this method much lower. so it just shows as a full add.

// incorporate the new document.
// If we're finalized and already frozen, we can just use ourselves.
if (state is FinalCompilationTrackerState { IsFrozen: true } finalState)
return this;
Copy link
Member Author

Choose a reason for hiding this comment

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

initial case. if we have nothing to do, do nothing :)

@CyrusNajmabadi
Copy link
Member Author

Although I realize you'll need diff states, not just the IDs, since our APIs at least would allow a document's file path to change without changing the ID.

ughhhhhhhh

@CyrusNajmabadi
Copy link
Member Author

@jasonmalinowski this is ready for another pass.

// Because we froze before ever even looking at anything semantics related, we should have no documents in
// this project.
var frozenSolution = await project.Solution.WithFrozenPartialCompilationsAsync(CancellationToken.None);
var frozenSolution = project.Solution.WithFrozenPartialCompilations(CancellationToken.None);
Copy link
Contributor

Choose a reason for hiding this comment

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

WithFrozenPartialCompilations

Out of curiosity, is the sync one preferred?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes. the sync one is preferred. if there is still an async one, i intend to remove it (can be done in followup). the general principle we want to follow is that this is available and synchronous for code that is intended ot be in low latency features, where they don't want to even do any work on a threadpool if avoidable.

Comment on lines +51 to +53
_cachedFrozenSolution = cachedFrozenSolution ?? new AsyncLazy<Solution>(
c => Task.FromResult(ComputeFrozenSolution(c)),
c => ComputeFrozenSolution(c));
Copy link
Member

Choose a reason for hiding this comment

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

Can this use your other helper? If this is coming in a queued PR then feel free to resolve this comment.

Copy link
Member Author

Choose a reason for hiding this comment

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

will do!

private ConditionalWeakTable<ISymbol, ProjectId?>? _unrootedSymbolToProjectId;
private static readonly Func<ConditionalWeakTable<ISymbol, ProjectId?>> s_createTable = () => new ConditionalWeakTable<ISymbol, ProjectId?>();

private readonly AsyncLazy<SolutionCompilationState> _cachedFrozenSnapshot;
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this just undoing #72193? Becuase I liked that one. I didn't undestand why we had AsyncLazies at both levels.

Copy link
Member Author

Choose a reason for hiding this comment

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

it's not quite undoing it. the cachgin, and what we hand out, is still cached Solution instances (which is good for downstream consumers). However, under the covers there are a couple of paths that get to asking for the frozen compilation state. And this ensures they can happen and still get the same result. this is not really that necessary though, and i will considering removing it. i just very much liked the idea that sharing woudl happen if possible.

@CyrusNajmabadi CyrusNajmabadi merged commit b927c71 into dotnet:main Feb 22, 2024
@CyrusNajmabadi CyrusNajmabadi deleted the frozenPartialOuter branch February 22, 2024 21:47
@jjonescz jjonescz added this to the 17.10 P2 milestone Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-IDE untriaged Issues and PRs which have not yet been triaged by a lead

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants