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

Replace BatchingWorkQueue with AsyncBatchingWorkQueue from Roslyn #10140

Merged
merged 17 commits into from
Mar 26, 2024

Conversation

DustinCampbell
Copy link
Member

@DustinCampbell DustinCampbell commented Mar 21, 2024

Fixes #10158

I recommend reviewing commit-by-commit.

Razor has had a BatchingWorkQueue for a long while that has dubious semantics. It is used by three features:

  • OpenDocumentGenerator - Listens for document updates, computes generated output for each, and notifies listeners when a document has been processed.
  • WorkspaceSemanticTokensRefreshPublisher - Called in the server to send the client semanticTokens/refresh notifications. This really sort of abuses BatchingWorkQueue just for debouncing and only send notifications every 250 milliseconds.
  • WorkspaceProjectStateChangeDetector - Listens for Roslyn workspace and Razor project manager changes and calls into IProjectWorkspaceStateGenerator.Update(...) when a change occurs.

This change fully replaces BatchingWorkQueue with a copy of Roslyn's AsyncBatchingWorkQueue, which has consistent semantics and has been battle-hardened for years. I've updated OpenDocumentGenerator and WorkspaceProjectStateChangeDetector above to use AsyncBatchingWorkQueue. For WorkspaceSemanticTokensRefreshPublisher (now WorkspaceSemanticTokensRefreshNotifier), I've removed the BatchingWorkQueue altogether and replaced it with simpler logic that debounces and calls Task.Delay(...).

Many thanks to @CyrusNajmabadi for his help with AsyncBatchingWorkQueue.

@dotnet/razor-compiler: The only relevant compiler changes are in shared code.

@DustinCampbell DustinCampbell requested review from a team as code owners March 21, 2024 19:25
@DustinCampbell DustinCampbell marked this pull request as draft March 21, 2024 19:46
@DustinCampbell DustinCampbell changed the title Replace BatchingWorkQueue with AsyncBatchingWorkQueue from Roslyn [DRAFT] Replace BatchingWorkQueue with AsyncBatchingWorkQueue from Roslyn Mar 21, 2024
@DustinCampbell DustinCampbell force-pushed the work-queues branch 3 times, most recently from ea8db69 to 21dbfae Compare March 21, 2024 20:47
@DustinCampbell
Copy link
Member Author

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@DustinCampbell DustinCampbell force-pushed the work-queues branch 4 times, most recently from c1f8f49 to 2814950 Compare March 21, 2024 23:49
@DustinCampbell DustinCampbell dismissed davidwengier’s stale review March 22, 2024 01:27

Approval was unintentional added to draft PR

@DustinCampbell DustinCampbell requested a review from a team March 22, 2024 01:31
Roslyn's `AsyncBatchingWorkQueue` is a battle-hardened utility that provides a robust mechanism to do work in batches without blocking.
…ations

`WorkspaceSemanticTokensRefreshNotifier` (previously `WorkspaceSemanticTokensRefreshPublisher`) uses a `BatchingWorkQueue` for debouncing, even though it isn't actually batching work. I've replaced this with much simpler code that just tracks a `Task` generated with `Task.Delay(...)`.
Remove invalid link from comment and make code style consistent.
@DustinCampbell
Copy link
Member Author

@CyrusNajmabadi, @davidwengier, @jjonescz: I've made further changes to pull the "most recent item" de-duping out of AsyncBatchingWorkQueue and into a helper method, if you're interested in taking another look.

Comment on lines +130 to +134
#if !NETSTANDARD2_0
var uniqueItems = new HashSet<T>(capacity: source.Length, comparer);
#else
var uniqueItems = new HashSet<T>(comparer);
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Can/Should this be pooled?

Copy link
Member Author

@DustinCampbell DustinCampbell Mar 25, 2024

Choose a reason for hiding this comment

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

Unfortunately, no. It can't because of the comparer. Like Dictionary<TKey, TValue>, there's no way to set a HashSet<T> comparer other than in the constructor.

@davidwengier
Copy link
Contributor

Still LGTM

@DustinCampbell DustinCampbell merged commit 3cd3804 into dotnet:main Mar 26, 2024
12 checks passed
@DustinCampbell DustinCampbell deleted the work-queues branch March 26, 2024 16:20
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Mar 26, 2024
@RikkiGibson
Copy link
Contributor

Heads up that there might be an RPS regression from this

Known good: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/538963
Known bad: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/539115
See details in the known bad.

@DustinCampbell
Copy link
Member Author

Heads up that there might be an RPS regression from this

Known good: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/538963 Known bad: https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/539115 See details in the known bad.

Possibly, but I'm not sure. There were similar RPS regressions in our 17.10p3 payload that have been fixed in the release/dev17.10 branch. We should get those fixes into main to be sure.

@davidwengier
Copy link
Contributor

The fixes have merged to main

@DustinCampbell
Copy link
Member Author

@RikkiGibson: Now that main has the release/dev17.10 fixes, is there an updated PR we can track?

@RikkiGibson
Copy link
Contributor

Latest main insertion is showing fewer assembly loads but still elevated from baseline https://dev.azure.com/devdiv/DevDiv/_git/VS/pullrequest/539887

@DustinCampbell
Copy link
Member Author

DustinCampbell commented Mar 28, 2024

I think that's going to require further investigation. Could you file an issue, start a mail thread, or raise this in Teams? It feels like the right eyes aren't going to see this on a closed PR. I'll start digging in though.

@RikkiGibson
Copy link
Contributor

Started the conversation on the infraswat side. Thanks!

@DustinCampbell
Copy link
Member Author

OK. I'm not on infraswat and probably won't see that. However, I suspect that @phil-allen-msft is. Just know that I'm actively investigating and working on a fix.

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.

Update BatchingDocumentGenerator to use AsyncBatchingWorkQueue
6 participants