bytecodealliance / bytecodealliance/wasmtime

Allow hosts to temporarily suspend individual Component Model async guest tasks

Open
#14,284 2 comments 0 reactions 0 assignees View on GitHub
wasm-proposal:component-model-async
Dominant language
Rust
Stars
18.6k
Forks
1.8k
Avg merge
1d 19h
Merged PRs (30d)
121

Description

#### Feature

Add some way for the host to temporarily make a Component Model async guest task ineligible to enter or resume guest execution.

The motivating case is similar to Cloudflare Durable Objects' `blockConcurrencyWhile`: if async exports A and B are running concurrently in the same component instance, A should be able to enter an exclusive section during which B executes no guest code, while A and host-side async work continue to make progress.

It could look like:

```rust
pause_task(task: GuestTaskId)
resume_task(task: GuestTaskId)
```

or some equivalent scheduler-level abstraction.

This seems related to #11896, which discusses pausing tasks in the concurrent scheduler while allowing a privileged debugger task to continue. I'm mainly interested in whether there is already an intended abstraction for this kind of scheduler control.

#### Benefit

This would allow an embedder to implement exclusive execution regions across concurrent Component Model async calls without requiring cooperation from the guest.

The important distinction from instance backpressure is that the affected task may already have started. It might be waiting for an event or already queued for thread/fiber resumption, so the restriction needs to apply to both starting and re-entering guest code.

While a task is paused:

* unrelated guest tasks should continue to run;
* host futures and I/O should continue to make progress;
* queued work for the paused task should be retained;
* if the task is currently executing, the pause can take effect when it next returns to the scheduler.

This would also seem useful as a more general scheduler primitive for cases such as the debugger work discussed in #11896.

#### Implementation

Current `main` appears to already carry `QualifiedThreadId` on both `ResumeThread` and `ResumeFiber`, so all guest-executing work items seem to have enough identity to associate them with a task.

One possible implementation would be to add a task-level scheduler eligibility check covering guest-call start/event delivery as well as thread/fiber resumption, and retain ineligible work until the task becomes runnable again.

I'm not sure whether the natural unit should be exactly one `GuestTaskId`, or a root export task together with work descended from it. For the motivating use case, root-task semantics would probably be more useful.

I'd be interested in whether this matches the scheduler direction already envisioned for #11896, or whether Wasmtime would model this differently.

#### Alternatives

One alternative is to implement the exclusion in the guest, for example by wrapping exports so that non-owning tasks return `Pending` while another task holds the exclusive section. That works, but requires cooperation from each guest language/runtime and therefore cannot be enforced by the host for arbitrary components.

Another alternative is to delay host-originated completion futures. That can prevent some event deliveries, but does not cover already-queued starts, guest-to-guest events, or thread/fiber resumption.

Instance backpressure is also insufficient because it only controls starting calls, not resuming already-started task

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.