next.js
362b1efe - fix(turbo-tasks): compile EventListener::wait on wasm (#97853)

Commit
10 days ago
fix(turbo-tasks): compile EventListener::wait on wasm (#97853) > Replaces #97579, which was **not merged**. Reordering this stack briefly left that PR > pointing at a base branch that had come to contain its own head commit, so GitHub closed it > as merged and deleted its branch. Nothing from it reached `canary`. It had been approved; > this PR is the same commit (`1d868fd710`), restored, and needs review again. Sorry for the churn. ### What? Gives `turbo_tasks::EventListener::wait` a working blocking implementation on wasm targets, instead of failing to compile there. Also moves `criterion` to a non-wasm dev-dependency, which is what makes `cargo test -p turbo-tasks --lib --target wasm32-wasip1-threads` buildable at all — see *How?*. ### Why? `event-listener` gates its blocking `wait()` / `wait_timeout()` / `wait_deadline()` behind `#[cfg(all(feature = "std", not(target_family = "wasm")))]`, so they are unavailable on **every** wasm target — even `wasm32-wasip1-threads`, which has real threads that can park. That made `EventListener::wait` fail to compile. This is load-bearing rather than a corner case: `wait()` backs the priority runner's task barriers (six call sites in `turbopack/crates/turbo-tasks/src/priority_runner.rs`) and `turbopack/crates/turbo-tasks/src/scope.rs`. Anything that merely compiled while `wait()` was unusable would be hollow. ### How? `event-listener`'s own native implementation (`wait_internal` → `wait_with_parker`) is just "register an unparker as the listener's task, then `Parker::park()` in a loop". `EventListener` already implements `Future`, so on wasm the same thing is expressed one level up: ```rust fn block_on_listener(listener: event_listener::EventListener) { #[cfg(not(target_family = "wasm"))] { use event_listener::Listener as _; listener.wait(); } #[cfg(target_family = "wasm")] futures::executor::block_on(listener); } ``` `futures` is already a dependency of this crate, `executor` is one of its default features, and `futures-executor` is already in the wasm dependency graph, so nothing new is pulled in. Native targets keep calling `event-listener` directly, so their behaviour and fast path are untouched. Both `wait()` implementations — the default one and the `hanging_detection` one — route through that single helper, so the two cannot drift apart and the target `cfg` exists in exactly one place. **Verification.** A new test registers a listener, spawns a thread that sleeps before notifying, then waits — so the listener parks first and the parking path is exercised rather than the already-notified fast path. It asserts both that the notifier ran *and* that time actually elapsed, so a `wait()` that returned early fails instead of silently passing. It passes natively, and the wasm code path was executed under wasmtime with real wasi threads on `wasm32-wasip1-threads`: the waiter blocked **300.9 ms** against a 300 ms notifier delay and was woken by the other thread. As a control, a deliberately non-blocking variant returns in ~1 µs and fails the assertions. Two notes on the surrounding tooling: - `criterion` is used only by the `[[bench]]` targets, but it pulls in `rayon`, which refuses to compile for wasi, and cargo resolves dev-dependencies even for `cargo test --lib`. Gating it to non-wasm targets is semantically right (the benchmarks don't run on wasm) and unblocks wasm test binaries for this crate generally. Native benchmarks are unaffected. - The test binary now *builds* for wasm but cannot be instantiated by a plain runtime, because `turbo-tasks` imports `env.read_custom_section` for its link-time task registries and no CLI runtime provides it. That hook is tracked separately; until it exists, the runtime evidence above comes from a standalone binary that copies the helper's wasm body verbatim against the same `event-listener` and `futures` versions. <!-- NEXT_JS_LLM --> <!-- fleet b6d0486f-97c7-42a7-bdaf-3490774cdec3 --> Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com> Co-authored-by: Luke Sandberg <210140+lukesandberg@users.noreply.github.com>
Author
Parents
Loading