worker-build --emscripten - #1061
Open
guybedford wants to merge 26 commits into
Open
guybedford wants to merge 26 commits into
guybedford wants to merge 26 commits into
Conversation
guybedford
added a commit
to guybedford/rust-workers-minecraft
that referenced
this pull request
Sep 16, 2026
The Worker now uses workers-rs (cloudflare/workers-rs#1061): the `worker` crate for the fetch handler, Env and Durable Object plumbing, and `worker-build --emscripten --tokio` to link the bin through emcc, wrap the exports into the entrypoint and DurableObject-derived class, and emit the module Wrangler serves. The JS shim, the factory link arguments in .cargo/config.toml and the wasm-bindgen CLI plumbing in the scripts go away; build.rs keeps only the application's own settings. The Durable Object no longer owns a runtime. `connect` is a `#[wasm_bindgen(tokio)]` export (wasm-bindgen/wasm-bindgen#5334) whose future runs on the thread's Tokio `LocalEventLoop` (tokio-rs/tokio#8484), the host event loop driving the scheduler. The server lifetime is spawned as a task so a panic arrives as a JoinError and fails the object. Pins move to the event-loop stack: tokio `emscripten-event-loop-host`, mio `emscripten`, workers-rs `gbedford/worker-build-emscripten` with its wasm-bindgen submodule supplying every wasm-bindgen crate, and emscripten `cf-final` with the emsdk release its main is paired with. Binaryen comes from that emsdk, so the separate Binaryen checkout and build are dropped.
Build Workers for wasm32-unknown-emscripten through a worker-build provisioned toolchain: the pinned emsdk release is installed into the cache directory and the frontend patched with backports the Rust link needs (marker-based -sWASM_BINDGEN, NODERAWSOCKETS DNS). rustc drives emcc as the linker for a bin target, emcc runs wasm-bindgen post-link, and the output is collected into the standard build/index.js shape. The worker crate's start function becomes private, since its public init export collided with Emscripten's own.
The exnref translation failure on debug builds was wasm-bindgen 0.2.128's --keep-debug output (walrus 0.27.1 .debug_loc), fixed on main by #5328, not binaryen on the linked module. The CLI floor already covers it.
The worker crate no longer registers the abort reinit hook on wasm32-unknown-emscripten, so the released wasm-bindgen CLI builds --emscripten --release; only debuginfo builds still need #5328. Export and wasm import detection now handle emcc's minified release output.
The runtime serves the whole cloudflare: namespace (cloudflare:node, cloudflare:test, ...), not only the three that were listed, and a wasm-bindgen module import of one of them must reach the output as an import rather than fail to resolve in esbuild.
Backport the JSPI lifecycle hooks, REENTRANT_JSPI fiber stacks and epoll listener API to the 6.0.9 frontend, and take Binaryen from a release carrying the jspi-hooks pass (WebAssembly/binaryen#9102). The release sysroot stamp is dropped after patching so emcc installs the new headers.
wasm-bindgen/wasm-bindgen#5333 instruments jspi exports and suspending imports with emscripten's fiber hooks, so under -sREENTRANT_JSPI each fetch activation runs on its own stack. The example takes wasm-bindgen from the submodule until it is released.
Pass --cfg tokio_jspi_hooks so Tokio's emscripten port registers the JSPI lifecycle hooks, and move the example to that Tokio branch. Concurrent fetch activations each drive their own runtime.
The runtime exposes RPC on a Durable Object class only when it derives from cloudflare:workers' DurableObject; the wasm-bindgen classes are plain, so splice its prototype in.
On wasm32-unknown-emscripten the handler wrappers are #[wasm_bindgen(jspi)] exports suspending on the handler future, so each activation is its own fiber. The wrappers are left for rustc to expand: expanding both cfg variants in the proc macro deduplicated their export descriptors.
`--emscripten --tokio` schedules each handler on a Tokio event-loop runtime per invocation (tokio-rs/tokio#8479), whose wait is the host event loop, so plain async handlers use tokio::net and tokio::time with no stack switching. `--emscripten --tokio=jspi` is the previous behaviour: JSPI exports on their own fibers blocking on a runtime. The mode reaches the macros as cfg(worker_tokio = ...). The epoll listener backport now delivers readiness through a macrotask: workerd drains microtasks synchronously inside builtin module loads, so a microtask delivery ran one runtime's drive under another's connect().
reentrant-jspi.patch now carries #27698, #27699 and #27547 at their heads (listener keepalive holds, teardown wakes, macrotask delivery) and noderawsockets-dns.patch carries #27693 at its head (node:dns only, no virtual /etc/hosts), both as exact diffs against the 6.0.9 tree.
epoll-listeners.patch carries #27547 at 34e2cc057 and #27720 (timeout keepalive release), noderawsockets-dns.patch carries #27693 as rebased onto that, and the JSPI hooks / REENTRANT_JSPI backport (#27698, #27699) moves to a trailing jspi-hooks.patch that only --tokio=jspi depends on.
The event-loop integration never needed stack switching, so --tokio=jspi, its lifecycle-hooks backport (jspi-hooks.patch), the -sJSPI link, the Binaryen release carrying the jspi-hooks pass, the tokio_jspi_hooks cfg and the JSPI export variant in worker-macros go. --tokio is a plain flag and the emsdk release supplies the whole backend. The noderawsockets-dns patch stays: without stack switching getaddrinfo returns EAI_AGAIN for hostnames, a clean io::Error instead of the host's uncaught "Invalid IP address" from net.connect.
tokio-rs/tokio#8484 replaces EventLoopRuntime with EventLoop / LocalEventLoop; the example takes tokio from its branch and mio from its emscripten branch (tokio-rs/mio#1969). The wasm-bindgen submodule moves to the rebuilt emscripten stack: main plus the reinit fix (#5332), legalized export names and the tokio attribute (#5334) adapted to LocalEventLoop, without the emscripten JSPI support. worker's schedule_isolated use is unchanged.
0.8.6 dropped them to release on stable wasm-bindgen; worker's tokio feature on wasm-bindgen-futures and #[wasm_bindgen(tokio)] come from the submodule until they ship.
Brings #[event(connect)] (#1041) in line with the other handlers so it runs on the Tokio event loop under --tokio.
guybedford
force-pushed
the
gbedford/worker-build-emscripten
branch
from
September 16, 2026 19:40
0873a5d to
35fde18
Compare
guybedford
added a commit
to guybedford/rust-workers-minecraft
that referenced
this pull request
Sep 16, 2026
The Worker now uses workers-rs (cloudflare/workers-rs#1061): the `worker` crate for the fetch handler, Env and Durable Object plumbing, and `worker-build --emscripten --tokio` to link the bin through emcc, wrap the exports into the entrypoint and DurableObject-derived class, and emit the module Wrangler serves. The JS shim, the factory link arguments in .cargo/config.toml and the wasm-bindgen CLI plumbing in the scripts go away; build.rs keeps only the application's own settings. The Durable Object no longer owns a runtime. `connect` is a `#[wasm_bindgen(tokio)]` export (wasm-bindgen/wasm-bindgen#5334) whose future runs on the thread's Tokio `LocalEventLoop` (tokio-rs/tokio#8484), the host event loop driving the scheduler. The server lifetime is spawned as a task so a panic arrives as a JoinError and fails the object. Pins move to the event-loop stack: tokio `emscripten-event-loop-host`, mio `emscripten`, workers-rs `gbedford/worker-build-emscripten` with its wasm-bindgen submodule supplying every wasm-bindgen crate, and emscripten `cf-final` with the emsdk release its main is paired with. Binaryen comes from that emsdk, so the separate Binaryen checkout and build are dropped.
guybedford
added a commit
to guybedford/rust-workers-minecraft
that referenced
this pull request
Sep 16, 2026
The Worker now uses workers-rs (cloudflare/workers-rs#1061): the `worker` crate for the fetch handler, Env and Durable Object plumbing, and `worker-build --emscripten --tokio` to link the bin through emcc, wrap the exports into the entrypoint and DurableObject-derived class, and emit the module Wrangler serves. The JS shim, the factory link arguments in .cargo/config.toml and the wasm-bindgen CLI plumbing in the scripts go away; build.rs keeps only the application's own settings. The Durable Object no longer owns a runtime. `connect` is a `#[wasm_bindgen(tokio)]` export (wasm-bindgen/wasm-bindgen#5334) whose future runs on the thread's Tokio `LocalEventLoop` (tokio-rs/tokio#8484), the host event loop driving the scheduler. The server lifetime is spawned as a task so a panic arrives as a JoinError and fails the object. Pins move to the event-loop stack: tokio `emscripten-event-loop-host`, mio `emscripten`, workers-rs `gbedford/worker-build-emscripten` with its wasm-bindgen submodule supplying every wasm-bindgen crate, and emscripten `cf-final` with the emsdk release its main is paired with. Binaryen comes from that emsdk, so the separate Binaryen checkout and build are dropped.
emscripten#27547 now delivers through unref'd handles with no listener keepalive of its own, and #27720 / #27693 are regenerated from their merged main commits. The example's tokio moves to 5ef5ab3d, where the event loop holds the runtime keepalive itself.
guybedford
added a commit
to guybedford/rust-workers-minecraft
that referenced
this pull request
Sep 17, 2026
The Worker now uses workers-rs (cloudflare/workers-rs#1061): the `worker` crate for the fetch handler, Env and Durable Object plumbing, and `worker-build --emscripten --tokio` to link the bin through emcc, wrap the exports into the entrypoint and DurableObject-derived class, and emit the module Wrangler serves. The JS shim, the factory link arguments in .cargo/config.toml and the wasm-bindgen CLI plumbing in the scripts go away; build.rs keeps only the application's own settings. The Durable Object no longer owns a runtime. `connect` is a `#[wasm_bindgen(tokio)]` export (wasm-bindgen/wasm-bindgen#5334) whose future runs on the thread's Tokio `LocalEventLoop` (tokio-rs/tokio#8484), the host event loop driving the scheduler. The server lifetime is spawned as a task so a panic arrives as a JoinError and fails the object. Pins move to the event-loop stack: tokio `emscripten-event-loop-host`, mio `emscripten`, workers-rs `gbedford/worker-build-emscripten` with its wasm-bindgen submodule supplying every wasm-bindgen crate, and emscripten `cf-final` with the emsdk release its main is paired with. Binaryen comes from that emsdk, so the separate Binaryen checkout and build are dropped.
The example's tokio moves to 067f92b6, where the emscripten event loop is built hosted: it schedules its own drives and holds the runtime keepalive while it has tasks. The wasm-bindgen submodule follows with the tokio attribute built on it; worker's use of schedule_isolated is unchanged.
guybedford
added a commit
to guybedford/rust-workers-minecraft
that referenced
this pull request
Sep 18, 2026
The Worker now uses workers-rs (cloudflare/workers-rs#1061): the `worker` crate for the fetch handler, Env and Durable Object plumbing, and `worker-build --emscripten --tokio` to link the bin through emcc, wrap the exports into the entrypoint and DurableObject-derived class, and emit the module Wrangler serves. The JS shim, the factory link arguments in .cargo/config.toml and the wasm-bindgen CLI plumbing in the scripts go away; build.rs keeps only the application's own settings. The Durable Object no longer owns a runtime. `connect` is a `#[wasm_bindgen(tokio)]` export (wasm-bindgen/wasm-bindgen#5334) whose future runs on the thread's Tokio `LocalEventLoop` (tokio-rs/tokio#8484), the host event loop driving the scheduler. The server lifetime is spawned as a task so a panic arrives as a JoinError and fails the object. Pins move to the event-loop stack: tokio `emscripten-event-loop-host`, mio `emscripten`, workers-rs `gbedford/worker-build-emscripten` with its wasm-bindgen submodule supplying every wasm-bindgen crate, and emscripten `cf-final` with the emsdk release its main is paired with. Binaryen comes from that emsdk, so the separate Binaryen checkout and build are dropped.
Regenerates the 6.0.9 backports from the current pull request heads: the epoll listeners are unchanged in content, the DNS patch gains emscripten_dns_lookup_async / emscripten_dns_lookup_result (#27742), and a new accept-blocking.patch carries the part of #27724 that reaches the single-threaded Node build, recv surfacing a pending socket error ahead of EOF.
guybedford
added a commit
to guybedford/rust-workers-minecraft
that referenced
this pull request
Sep 18, 2026
The Worker now uses workers-rs (cloudflare/workers-rs#1061): the `worker` crate for the fetch handler, Env and Durable Object plumbing, and `worker-build --emscripten --tokio` to link the bin through emcc, wrap the exports into the entrypoint and DurableObject-derived class, and emit the module Wrangler serves. The JS shim, the factory link arguments in .cargo/config.toml and the wasm-bindgen CLI plumbing in the scripts go away; build.rs keeps only the application's own settings. The Durable Object no longer owns a runtime. `connect` is a `#[wasm_bindgen(tokio)]` export (wasm-bindgen/wasm-bindgen#5334) whose future runs on the thread's Tokio `LocalEventLoop` (tokio-rs/tokio#8484), the host event loop driving the scheduler. The server lifetime is spawned as a task so a panic arrives as a JoinError and fails the object. Pins move to the event-loop stack: tokio `emscripten-event-loop-host`, mio `emscripten`, workers-rs `gbedford/worker-build-emscripten` with its wasm-bindgen submodule supplying every wasm-bindgen crate, and emscripten `cf-final` with the emsdk release its main is paired with. Binaryen comes from that emsdk, so the separate Binaryen checkout and build are dropped.
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.
This adds
worker-build --emscripten, building Workers forwasm32-unknown-emscriptenso crates that need a libc, epoll sockets or blocking calls (stock Tokionet, etc.) run unmodified, parking through JSPI.worker-build/patches/emscripten/to the frontend: the marker-based-sWASM_BINDGENbackport (Unify wasm-bindgen output under -sWASM_BINDGEN with marker-based detection emscripten-core/emscripten#27208) and NODERAWSOCKETS DNS (Real DNS resolution for getaddrinfo under -sNODERAWSOCKETS emscripten-core/emscripten#27693). Each is dropped as the pin moves past it.EMSCRIPTEN/EMSDKenv vars override for local toolchain work.emccas the linker for a bin target (cdylib cannot link on emscripten); emcc runs wasm-bindgen post-link, and the output is collected into the standardbuild/index.js+ wasm shape, so wrangler config only changes the build command (plus thenew_module_registrycompat flag forimport.meta.url). Codegen and link flags go throughRUSTFLAGS, as--panic-unwinddoes.worker::initbecomes a private start function (its publicinitexport collided with Emscripten's own) and no longer registers the abort reinit hook on emscripten, where Emscripten owns instantiation.emscripten-tcpexample documents the[patch.crates-io]block.--releasebuilds work with the released wasm-bindgen CLI. Debuginfo builds need a CLI with wasm-bindgen/wasm-bindgen#5328 (DWARF that survives the exnref translation) until 0.2.129; the submodule is updated to include it along with wasm-bindgen/wasm-bindgen#5332.Tested: the
emscripten-tcpexample (workertypes +tokio::net::TcpStreamunder JSPI) builds with--devand--releaseand serves/?host=example.comunderwrangler dev; CI adds anEmscripten examplejob running both builds and that smoke test. Unit tests cover the patch applier.