Implement Circuit.RequestCircuitPauseAsync#66265
Merged
ilonatommy merged 13 commits intomainfrom Apr 22, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a server-initiated entry point for Blazor Server’s existing graceful pause/resume flow by introducing a new Circuit.RequestCircuitPauseAsync API and wiring a new JS.RequestPause SignalR message that triggers the client-side pause UI/handshake.
Changes:
- Introduces public API
Circuit.RequestCircuitPauseAsync(...)and implements server-side dispatch viaCircuitHost.RequestPauseAsync(...). - Adds client-side handler for
JS.RequestPausethat triggers the existingCircuitManager.pause(remote: true)path. - Adds new unit and E2E coverage plus a test page/handler in
Components.TestServerto exercise server-triggered pause/resume scenarios.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Components/Web.JS/src/Platform/Circuits/CircuitManager.ts | Handles JS.RequestPause by invoking client pause flow |
| src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/PersistentState/ServerPauseTest.razor | Test page + JS-invokable entry to trigger server pause by circuit id |
| src/Components/test/testassets/Components.TestServer/RazorComponentEndpointsStartup.cs | Registers a circuit handler used to track circuits for the test page |
| src/Components/test/testassets/Components.TestServer/PauseTrackingHandler.cs | Tracks active circuits so the test can find the correct Circuit instance |
| src/Components/test/E2ETest/ServerExecutionTests/ServerTriggeredPauseTest.cs | New E2E tests validating server-triggered pause behavior and UI |
| src/Components/Server/test/Circuits/CircuitRegistryTest.cs | Adds coverage for stale connection-id pause behavior after reconnect |
| src/Components/Server/test/Circuits/CircuitHostTest.cs | Adds unit coverage for server pause request acceptance/rejection paths |
| src/Components/Server/src/PublicAPI.Unshipped.txt | Declares the newly added public API for validation |
| src/Components/Server/src/Circuits/CircuitHost.cs | Implements server-side pause request dispatch and logging |
| src/Components/Server/src/Circuits/Circuit.cs | Exposes the new RequestCircuitPauseAsync public API |
oroztocil
approved these changes
Apr 16, 2026
javiercn
reviewed
Apr 17, 2026
javiercn
reviewed
Apr 22, 2026
The callback controls timing, not permission. The pause always happens once the promise resolves. This matches javiercn's feedback that the framework owns the decision, the app owns the timing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
javiercn
approved these changes
Apr 22, 2026
Member
javiercn
left a comment
There was a problem hiding this comment.
Looks great!
I have to take a second look later, but I don't want to block on it.
Member
Author
|
/backport to release/11.0-preview4 |
Contributor
|
Started backporting to |
10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Design doc: #66244
Test scenarios covered: #66244 (comment). G2 remains uncovered: the scenario describes a correct existing behavior that can't be deterministically tested without a framework-internal hook in JS, which we chose not to add.
Fixes #62327.
New API
How it works
Dispatcher scheduling for sync work:
RequestCircuitPauseAsyncdispatches theJS.RequestPausesend onto the circuit's dispatcher viaRenderer.Dispatcher.InvokeAsync. This serializes it with any current sync work (rendering, synchronous event handlers) — the pause message is never sent while a render batch is being produced.Client hook for async work: The dispatcher cannot reliably detect completion of async work (event handlers at
awaitpoints, async component lifecycle methods). A child component's asyncOnParametersSetAsync, for example, creates a new renderer work item outside the scope of the original inbound handler. Instead of tracking this on the server, the client receivesJS.RequestPauseand can defer the actual pause via an optionalonPauseRequestedcallback inCircuitStartOptions:If the callback returns
false, the pause is deferred — the client does not callPauseCircuit. The server'sRequestCircuitPauseAsyncstill returnstrue(the message was accepted and sent). Without a callback, the client pauses immediately upon receivingJS.RequestPause.State validation: The method checks four conditions before accepting:
_initialized)OnConnectionUpAsynchas fired (_onConnectionUpFired)Telemetry: 4 log events —
ServerPauseRequested(120),ServerPauseAccepted(121),ServerPauseRejected(122),ServerPauseFailed(123).OperationCanceledExceptionlogs as rejected, other exceptions log as failed.