Stream: general

Topic: wac-graph prevents wit-bindgen::spawn_local from polling?


view this post on Zulip David Craven (Oct 05 2026 at 12:28):

seems like when multiple components are composed with wac-graph, block_on no longer polls futures spawned with wit-bindgen::spawn_local, is that accurate?

view this post on Zulip David Craven (Oct 05 2026 at 14:24):

is wit-bindgen::spawn_local even still supposed to be used? or was it just not removed in wasip3? and shouldn't std::thread::spawn work now in wasip3 as an alternative?

view this post on Zulip David Craven (Oct 05 2026 at 14:34):

well, looks like wasip3 isn't quite ready to be the user space for a microkernel then. shame, because was this close to getting a wasip3 hello world running, but just can't implement the wasi api's:

scripts/boot.sh
exec 1
wos: starting PID1
run 1
recv 1 Irq(8)
suspend 1
run 1
send 1 Irq(8)
Hello, world!
exec 2
suspend 1
run 2
suspend 2
run 1
suspend 1
run 2
block 2
suspend 2
run 1
send 1 Ipc(2)
block 1
suspend 1
run 2
recv 2 Ipc(1)
suspend 2
run 2
send 2 Ipc(1)
exit 2 with error UnreachableCodeReached
run 1
recv 1 Ipc(2)
send 1 Irq(8)
panic PanicHookInfo { payload: Any { .. }, location: Location { file: "/home/dvc/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wit-bindgen-0.62.0/src/rt/async_support/waitable.rs", line: 244, column: 13 }, can_unwind: true, force_no_backtrace: false }block 1
suspend 1

view this post on Zulip David Craven (Oct 05 2026 at 14:37):

impl exports::wasi::cli::stdout::Guest for WasiHandler {
    fn write_via_stream(stream: StreamReader<u8>) -> FutureReader<Result<(), ErrorCode>> {
        fn f() -> Result<(), ErrorCode> {
            Ok(())
        }
        let (writer, reader) = wit_future::new(f);
        /*std::thread::spawn(|| {
            panic!("spawning thread");
            wit_bindgen::block_on(async move {
                let bytes = stream.collect().await;
                while CONFIG
                    .get()
                    .unwrap()
                    .stdout
                    .send(bytes.clone())
                    .await
                    .is_err()
                {}
                writer.write(Ok(()));
            })
        });*/
        reader
    }
}

view this post on Zulip Adam Bratschi-Kaye (he) (Oct 05 2026 at 14:58):

I'm not sure why composing components would prevent spawn_local from working? It does have the limitations described in the docs, but should otherwise work. Do you have a repro?

view this post on Zulip David Craven (Oct 05 2026 at 16:04):

here's a repro: https://github.com/dvc94ch/wac-repro
to build run ./build.sh, it hangs indefinitely because wit_bindgen::spawn_local is never polled

view this post on Zulip David Craven (Oct 05 2026 at 17:05):

my hypothesis for why it isn't possible is because wit-bindgen::block_on polls the tasks that were spawned in its memory using the static mut TASKS, and when composing the globals are isolated, so when the first component calls wit-bindgen::block_on it can't see the ones spawned in the other component

view this post on Zulip David Craven (Oct 05 2026 at 17:06):

but I'm not sure what the correct way of doing it is supposed to be

view this post on Zulip David Craven (Oct 06 2026 at 11:09):

never mind, decided that a microkernel is the wrong approach. with rust/cargo there isn't much point in splitting an OS into microservices or pushing them into user space anyway and the performance tax is real

view this post on Zulip Adam Bratschi-Kaye (he) (Oct 06 2026 at 12:19):

I think the issue in your repro was that write-via-stream is sync lifted. So there's no way for it to keep running after it returns (only async lifts can do that).

view this post on Zulip David Craven (Oct 06 2026 at 17:21):

have most of cli/random/clocks functional, should be able to get the rest working tomorrow.
exec 1
boot at 19:19:14 06.10.2026
run 1
send 1 Irq(8)
Hello, world at 19:19:14
suspend 1
run 1
send 1 Irq(8)
random bytes [196, 144, 86, 232, 59, 5, 210, 228, 71, 99, 123, 178, 119, 241, 179, 131, 50, 111, 166, 10, 15, 193, 229, 190, 227, 241, 151, 80, 91, 255, 236, 25]
send 1 Irq(8)

thread 'main' (1) panicked at app/src/main.rs:23:5:
let's panic!
send 1 Irq(8)
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
exit 1 with error UnreachableCodeReached


Last updated: Oct 11 2026 at 04:10 UTC