mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-27 09:23:09 +00:00
116 lines
3.6 KiB
Markdown
116 lines
3.6 KiB
Markdown
|
|
# weft-runtime: Wasmtime Integration Plan
|
||
|
|
|
||
|
|
**Status:** Not yet implemented. weft-runtime currently stubs execution with `println!("READY")`.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Current State
|
||
|
|
|
||
|
|
`crates/weft-runtime/src/main.rs` resolves the package directory, validates `app.wasm`
|
||
|
|
exists, then prints `READY\n` and exits. No Wasm code is executed.
|
||
|
|
|
||
|
|
The stub satisfies the supervisor contract (described in `docs/architecture/app-package-format.md`)
|
||
|
|
and allows the full session lifecycle to be tested end-to-end.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Required Changes
|
||
|
|
|
||
|
|
### 1. Optional feature gate
|
||
|
|
|
||
|
|
Add a `wasmtime` cargo feature to `weft-runtime/Cargo.toml` so the default build remains
|
||
|
|
fast:
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[features]
|
||
|
|
default = []
|
||
|
|
wasmtime-runtime = ["dep:wasmtime"]
|
||
|
|
|
||
|
|
[dependencies]
|
||
|
|
wasmtime = { version = "30", optional = true, features = ["wasi"] }
|
||
|
|
```
|
||
|
|
|
||
|
|
`cfg(feature = "wasmtime-runtime")` guards the real implementation.
|
||
|
|
`cfg(not(feature = "wasmtime-runtime"))` keeps the stub for tests and development.
|
||
|
|
|
||
|
|
The production service unit (`infra/systemd/weft-appd.service`) would set
|
||
|
|
`WEFT_RUNTIME_BIN` to a binary built with `--features wasmtime-runtime`.
|
||
|
|
|
||
|
|
### 2. Engine and module setup
|
||
|
|
|
||
|
|
```rust
|
||
|
|
use wasmtime::{Config, Engine, Module, Store};
|
||
|
|
use wasmtime_wasi::{WasiCtxBuilder, preview1};
|
||
|
|
|
||
|
|
let engine = Engine::new(Config::default())?;
|
||
|
|
let module = Module::from_file(&engine, &wasm_path)?;
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. WASI context
|
||
|
|
|
||
|
|
```rust
|
||
|
|
let wasi = WasiCtxBuilder::new()
|
||
|
|
.inherit_stdout()
|
||
|
|
.inherit_stderr()
|
||
|
|
.build();
|
||
|
|
let mut store = Store::new(&engine, wasi);
|
||
|
|
```
|
||
|
|
|
||
|
|
stdout is inherited so the Wasm module can write `READY\n` directly via WASI
|
||
|
|
`fd_write` (standard output fd=1).
|
||
|
|
|
||
|
|
### 4. READY signal timing
|
||
|
|
|
||
|
|
The READY signal to weft-appd must be sent after module initialization but before
|
||
|
|
the main event loop blocks. Two options:
|
||
|
|
|
||
|
|
**Option A (simpler):** weft-runtime prints `READY\n` before calling the Wasm entry
|
||
|
|
point. The Wasm module is responsible for being ready to handle requests when it
|
||
|
|
starts running.
|
||
|
|
|
||
|
|
**Option B (accurate):** The Wasm module exports a `weft_ready()` function that
|
||
|
|
weft-runtime calls explicitly before starting the main event loop. The ready signal
|
||
|
|
is sent after `weft_ready()` returns.
|
||
|
|
|
||
|
|
Initial implementation should use Option A. Option B requires a convention on the
|
||
|
|
Wasm module's exported interface.
|
||
|
|
|
||
|
|
### 5. Entry point call
|
||
|
|
|
||
|
|
```rust
|
||
|
|
let linker = wasmtime_wasi::preview1::add_to_linker_sync(&engine)?;
|
||
|
|
let instance = linker.instantiate(&mut store, &module)?;
|
||
|
|
println!("READY");
|
||
|
|
let start = instance.get_typed_func::<(), ()>(&mut store, "_start")?;
|
||
|
|
start.call(&mut store, ())?;
|
||
|
|
```
|
||
|
|
|
||
|
|
`_start` is the standard WASI entry point generated by Rust's `wasm32-wasi` target.
|
||
|
|
|
||
|
|
### 6. Error handling
|
||
|
|
|
||
|
|
- `Module::from_file` failure: exit with non-zero code (weft-appd supervisor logs it).
|
||
|
|
- `_start` trap: log the trap message, exit non-zero.
|
||
|
|
- No `_start` export: log and exit non-zero. The package checker (`weft-pack`) should
|
||
|
|
eventually validate this at install time.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## What Is Not Designed
|
||
|
|
|
||
|
|
- **Host function imports**: Wasm modules that import host functions beyond WASI are not
|
||
|
|
supported in the initial implementation. Custom host bindings are deferred.
|
||
|
|
- **Memory limits**: no per-session memory cap is enforced. Deferred to capability model.
|
||
|
|
- **Wasm component model**: not used. Wasm 2.0 module format only.
|
||
|
|
- **Multi-threading (WASM threads)**: not enabled.
|
||
|
|
- **Fuel metering**: not enabled.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Prerequisite
|
||
|
|
|
||
|
|
Before implementing: confirm the target Wasm module compilation pipeline. The WEFT
|
||
|
|
app SDK must produce a valid `wasm32-wasi` binary that exports `_start`. Until an
|
||
|
|
example app exists that can be tested, the Wasmtime integration cannot be verified
|
||
|
|
end-to-end.
|