tiny-async-runtime#
tiny-async-runtime is a minimal, WASI-compatible async runtime designed to run on WebAssembly with WASI Preview 2. It provides:
- Single-threaded cooperative task scheduling
- Futures spawning and cancellation
- Timeout support
- Socket I/O integration
- File IO integration
This runtime is inspired by mio but is purpose-built for WASI environments.
Running In The Right Environment#
This crate is meant to be validated in a WASI Preview 2 host, not as a plain native executable.
- The socket support depends on Preview 2 imports from
wit/world.wit. - Native host runs such as
cargo teston Windows or Linux do not provide those imports. - The intended validation path is
cargo test --target wasm32-wasip2, executed underwasmtime.
The repository already includes a target runner in .cargo/config.toml, so if wasmtime is installed you can run:
cargo test --target wasm32-wasip2
cargo run --target wasm32-wasip2 --example basic_usage
Features#
-
block_on()Runs an async function to completion, driving timers, I/O readiness, and spawned tasks. -
#[tiny_wasm_runtime::main]Wraps anasync fninWasmRuntimeAsyncEngine::block_on(...), similar totokio::main. -
spawn()Launches a future in the runtime. Returns aJoinHandlefor cancellation or awaiting completion. -
Timers
Timer::sleep(duration)creates a future that resolves after a given time.- Timer futures integrate into the same event loop.
-
Cancellation
- Calling
JoinHandle::cancel()removes the task from the scheduler. - Owned timers and pollables are cleaned up when a task is canceled.
- Awaiting a canceled join handle still does not return a structured cancellation result.
- Calling
-
Partial socket support
- The current implementation covers connect, accept, read, and write flows on top of WASI Preview 2 sockets.
Example#
Here is a minimal example using block_on and spawn:
use tiny_wasm_runtime::{Timer, WasmRuntimeAsyncEngine};
fn main() {
WasmRuntimeAsyncEngine::block_on(async {
let handle = WasmRuntimeAsyncEngine::spawn(async {
Timer::sleep(std::time::Duration::from_secs(1)).await;
42
});
let result = handle.await;
println!("Background task returned: {result}");
});
}
You can also use the attribute macro:
use tiny_wasm_runtime::{Timer, WasmRuntimeAsyncEngine};
#[tiny_wasm_runtime::main]
async fn main() {
let handle = WasmRuntimeAsyncEngine::spawn(async {
Timer::sleep(std::time::Duration::from_millis(25)).await;
12
});
println!("Result: {}", handle.await);
}
Validated Example#
A runnable example lives at examples/basic_usage.rs.
It demonstrates:
WasmRuntimeAsyncEngine::block_onWasmRuntimeAsyncEngine::spawnTimer::sleepTimer::timeout
Run it in the Preview 2 environment with:
cargo run --target wasm32-wasip2 --example basic_usage
There is also a macro-based example at examples/macro_main.rs:
cargo run --target wasm32-wasip2 --example macro_main
More Docs#
For a deeper walkthrough, see:
docs/ARCHITECTURE.mddocs/DEVELOPMENT.md