Skip to content

Conversation

DustinCampbell
Copy link
Member

@DustinCampbell DustinCampbell commented Mar 19, 2025

The goal of this change is to move DocumentKey close to ProjectKey and use it various async batching work queues rather than holding onto project or document snapshots. I recommend reviewing commit-by-commit. Each commit describes its changes.

CI Build: https://dev.azure.com/dnceng/internal/_build/results?buildId=2668867&view=results
Test Insertion: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/621273

- Move DocumentKey to Microsoft.AspNetCore.Razor.ProjectEngineHost project alongside ProjectKey.
- Move DocumentKey to the Microsoft.AspNetCore.Razor.ProjectSystem namespace
- Rename DocumentFilePath to FilePath. ("Document" is a bit redundant in a "DocumentKey").
- Implement IComparable<ProjectKey> on ProjectKey.
- Implement IComparable<DocumentKey> on DocumentKey.
- Move ProjectKeyTests to Microsoft.AspNetCore.Razor.ProjectEngineHost.Test project
- Delete TestProjectKey. This is a pretty old helper and creates a pretty dubious ProjectKey. The few tests that still used this have been updated and fixed where necessary.
- Add tests for comparing ProjectKeys.
- Add tests for comparing DocumentKeys.
This adds two overloads to GetMostRecentUniqueItems. The first overload takes a HashSet<T> instead of an IEqualityComparer<T>. This allows a caller to avoid an allocation by passing an empty set. The second overload doesn't take an additional argument. Instead, it acquires a set from HashSetPool<T>.
- Add ProjectSnapshotManager.ContainsDocument(DocumentKey) extension method
- Add ProjectSnapshotManager.TryGetDocument(DocumentKey, ...) extension method
- Add ProjectSnapshotManager.GetDocument(DocumentKey) extension method
- Add ProjectSnapshotManager.GetRequiredDocument(DocumentKey) extension method
- Add ProjectSnapshotManager.Updater.ContainsDocument(DocumentKey) extension method
- Add ProjectSnapshotManager.Updater.TryGetDocument(DocumentKey, ...) extension method
- Add ProjectSnapshotManager.Updater.GetDocument(DocumentKey) extension method
- Add ProjectSnapshotManager.Updater.GetRequiredDocument(DocumentKey) extension method
Update ProjectStateChangeDetector to use a dedicated HashSet instance to compute the most recent unique items.
Update AbstractRazorProjectInfoDriver to use a dedicated HashSet instance to compute the most recent unique items.
Update OpenDocumentGenerator to use a dedicated HashSet instance to compute the most recent unique items. In addition, make the following changes:

- Add a DocumentSnapshot.Key property that produces a DocumentKey.
- Update OpenDocumentGenerator's async batching work queue to track DocumentKeys rather than DocumentSnapshots.
- Prefer faster boolean tests first, but checking _options.UpdateBuffersForCLosedDocuments before _projectManager.IsDocumentOpen(...)
Update IFallbackProjectManager.IsFallbackProject(...) to take a ProjectKey rather than a ProjectSnapshot. In addition, this commit includes a couple of changes to reorder some checks to avoid creating a ProjectSnapshot if it's not a fallback project.
Update BackgroundDocumentGenerator to use a dedicated HashSet instance to compute the most recent unique items. This is a larger change that makes BackgroundDocumentGenerator track work by DocumentKey rather than (ProjectSnapshot, DocumentSnapshot):

- Update BackgroundDocumentGenerator's async batching work queue to track DocumentKeys rather than (ProjectSnapshot, DocumentSnapshot).
- Update document suppression to use DocumentKey.
@DustinCampbell DustinCampbell requested review from a team as code owners March 19, 2025 15:56
Copy link
Member

@davidwengier davidwengier left a comment

Choose a reason for hiding this comment

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

LGTM. I could see subtle bugs being introduced from delaying things a bit more now (ie, the document/project processed is not the document/project queued) but those seem like good bugs to find and fix.

When iterating over `ProjectSnapshot.DocumentFilePaths`, it is redundant to call `ContainsDocument(...)` for those file paths on the same project. We already know it contains those file paths.
Move a logging message from the point that a document is enqueued to the point that is dequeued and processed. This also avoids instantiating a DocumentSnapshot to get its Version until later.
Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

Shared change LGTM.

- Change ProjectSnapshot.GetRelatedDocuments(DocumentSnapshot) to GetRelatedDocumentFIlePaths(string) that takes a document file path and returns document file paths. This avoids creating DocumentSnapshots unnecessarily to call this method or for the result.
- Make OpenDocumentGenerator and BackgroundDocumentGenerator ProjectManager_Changed effectively match.
- Rename BackgroundDocumentGenerator.Enqueue to EnqueueIfNecessary to match OpenDocumentGeneator.
- Merge ProjectAdded and ProjectChanged cases in BackgroundDocumentGenerator since they match.
- Add ProjectAdded case in OpenDocumentGenerator. This is probably a no-op, but it matches BackgroundDocumentGenerator.
- Add _solutionClosing flag to OpenDocumentGenerator to match BackgroundDocumentGenerator.
@DustinCampbell
Copy link
Member Author

@davidwengier: Just wanted to note that the most recent commit has more significant changes that you might want to take a look at.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants