Skip to content
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

Use DocumentKey to avoid holding Razor project/document snapshots when the most recent will be used. #11644

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

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=2667320&view=results
Test Insertion: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/620536

- 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.

{
return;
}

_logger.LogDebug($"Enqueuing generation of {document.FilePath} in {document.Project.Key.Id} at version {document.Version}");
_logger.LogDebug($"Enqueuing generation of {documentKey.FilePath} in {documentKey.ProjectKey.Id} at version {documentVersion}");
Copy link
Member

Choose a reason for hiding this comment

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

Seems like this log message should be moved into the actual processing method, as the version of the the document being processed could be different to what is logged here. Alternatively, could leave this and add a new log in the process method with the version actually being dealt with, so we can tell if things are getting delayed

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.

2 participants