dotnet / dotnet/aspnetcore

[Validation] Cancellation and timeouts on WebWorkerClient calls

Open
#68,819 1 comment 0 reactions 1 assignee Claimed by @MohamedHasan3644 View on GitHub
area-blazor Validation validation-scenario
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 6h
Merged PRs (30d)
290

Description

**Scenario contact:** @ilonatommy

## Scenario

Work sent to a background thread does not always come back. The worker may take longer than the user is willing to wait, the user may navigate away, or the worker may get stuck and never answer at all. `WebWorkerClient` accepts a cancellation token and a timeout on both worker creation and each invocation, so a caller can give up and tear down a stuck worker cleanly. This validates that giving up actually works, and that the app is left in a usable state afterwards.

## Minimum build

.NET 11 Preview 7 or later.

## Configurations to cover

* Blazor Web App
* [ ] Static SSR
* [ ] Interactive Server
* [x] Interactive WebAssembly
* [ ] Interactive Auto
* [x] Standalone WebAssembly
* [ ] Hybrid (MAUI)

## Also exercise

* [x] Published output
* [ ] An existing .NET 10 app upgraded to .NET 11
* [ ] Trimming or ahead-of-time compilation
* [ ] More than one server instance, or a proxy in front
* [ ] Hot Reload
* [ ] An IDE as well as the command line
* [ ] Container

## Setup

Create a worker project with `dotnet new blazorwebworker` and reference it from a Blazor app that renders on the client.

## What to build

A page with a Cancel button and a field for setting a timeout in milliseconds, so both can be exercised by hand rather than only in code.

In the worker project, add `[JSExport]` methods that make giving up meaningful: one that takes several seconds and then returns, one that never returns at all, and one that finishes almost instantly. Call them through `WebWorkerClient`, passing a `CancellationToken` from the Cancel button and the timeout from the field. Keep a visible log of what each call did: returned, cancelled, timed out, or something else.

Create the client with a timeout and a cancellation token too, not only the invocations, since both accept them.

## Things to try

* Cancelling a slow call part way through, then making a fresh call afterwards.
* Setting a timeout shorter than the slow method takes.
* Setting a timeout longer than the slow method takes, so it completes normally.
* Calling the method that never returns, with a timeout, and then again without one.
* Cancelling a call that has already completed.
* Cancelling the token before making the call at all.
* Cancelling worker creation itself, rather than an invocation.
* Cancelling one of several calls that are in flight together, and checking the others are unaffected.
* Disposing the client while a call is timing out.
* Repeating the cancel and timeout cycle many times over, watching for workers left behind in the browser's developer tools.

## Expected behavior

A caller who gives up gets control back promptly, and the app carries on working.

### Must hold

* Cancelling an in-flight call returns control to the caller promptly, rather than waiting for the worker to finish.
* A call that exceeds its timeout fails rather than hanging, including the method that never returns.
* Cancellation and timeout are distinguishable from an ordinary failure, so the app can tell the user which happened.
* After a cancelled or timed-out call, a fresh call on a new client succeeds.
* Cancelling one of several concurrent calls leaves the others to complete normally.
* Repeated cancel and timeout cycles leave no growing number of workers in the browser's developer tools.
* No unhandled error appears in the browser console during any cancellation, timeout or disposal.

### Expected differences between configurations

* No differences are expected between Standalone WebAssembly and a Blazor Web App's Interactive WebAssembly pages.

## Evidence to capture

The browser's list of running workers after ten cancel and timeout cycles, alongside the same list before you started.

## Documentation to use

* [New Blazor Web Worker template, .NET 11 release notes](https://learn.microsoft.com/aspnet/core/release-notes/aspnetcore-11#new-blazor-web-worker-template-blazorwebworker)
* [ASP.NET Core Blazor with .NET on web workers](https://learn.microsoft.com/aspnet/core/blazor/blazor-with-dotnet-on-web-workers?view=aspnetcore-11.0)

## What to report

Report results using the format described in the [validation testing manual](https://github.com/dotnet/aspnetcore/issues/68479). Include link to a repository with the test app.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.