Idea
Compile all wasm routing-policy presets into a single embedded .wasm module instead of one artifact per policy, and expose them through the existing preset:<name> mechanism — applying the same registry pattern the Starlark presets already use.
Why
Each standalone TinyGo wasm policy (docs/examples/routing-policies/wasm/*/*.wasm) is ~500KB, of which ~450KB is the TinyGo runtime and only a few KB is the actual policy. Shipping N of them separately duplicates that runtime N times (~5MB for 10 policies). One combined module pays the runtime once: 1 × ~450KB + N × few-KB ≈ ~0.5MB for 10 policies.
How it maps onto existing patterns
- Starlark presets today:
preset:<name> → presets.Source(name) returns inline text embedded in the binary (pkg/router/policy/presets, presets.Source()/presets.Names(), resolved in pkg/router/policy/loader.go).
- WASM equivalent: a new
pkg/router/policy/wasm/presets package with one //go:embed presets.wasm and a Names()/registry surface mirroring the Starlark one. The combined guest holds an internal map[string]func(ctx) RouteSpec.
Implementation notes
- ABI-compatible dispatch by name. The host already JSON-encodes the input for
decide_route(in_ptr,in_len) (pkg/router/policy/wasm/abi.go/host.go). Add a preset field; the combined guest's single decide_route switches into the registry. Same for optional on_leg_change/on_tick. No new exports, no ABI break.
- State isolation for stateful presets (e.g. rotating-bw uses
on_tick): CompileModule once (cached), InstantiateModule per active preset — the evaluator already instantiates per-loader (pkg/router/policy/wasm/evaluator.go), so each bound preset gets its own linear memory / guest globals with no cross-talk.
- Name resolution: when a name exists in both backends (e.g. app-mux has a
.star twin), resolve wasm-first when the combined bundle provides it (faster per-call), Starlark otherwise — or add a wasm:/star: disambiguator.
- Build step: a
make target compiling the bundle under TinyGo (wasi), same lane as build-wasm-tinygo.
Related
Follow-up from the wasm-visor proxy-reliability work (#3939) and the transport-cost survey (#3941). The Starlark preset comparison is deferred; wasm presets are preferred for per-call speed.
Idea
Compile all wasm routing-policy presets into a single embedded
.wasmmodule instead of one artifact per policy, and expose them through the existingpreset:<name>mechanism — applying the same registry pattern the Starlark presets already use.Why
Each standalone TinyGo wasm policy (
docs/examples/routing-policies/wasm/*/*.wasm) is ~500KB, of which ~450KB is the TinyGo runtime and only a few KB is the actual policy. Shipping N of them separately duplicates that runtime N times (~5MB for 10 policies). One combined module pays the runtime once:1 × ~450KB + N × few-KB≈ ~0.5MB for 10 policies.How it maps onto existing patterns
preset:<name>→presets.Source(name)returns inline text embedded in the binary (pkg/router/policy/presets,presets.Source()/presets.Names(), resolved inpkg/router/policy/loader.go).pkg/router/policy/wasm/presetspackage with one//go:embed presets.wasmand aNames()/registry surface mirroring the Starlark one. The combined guest holds an internalmap[string]func(ctx) RouteSpec.Implementation notes
decide_route(in_ptr,in_len)(pkg/router/policy/wasm/abi.go/host.go). Add apresetfield; the combined guest's singledecide_routeswitches into the registry. Same for optionalon_leg_change/on_tick. No new exports, no ABI break.on_tick):CompileModuleonce (cached),InstantiateModuleper active preset — the evaluator already instantiates per-loader (pkg/router/policy/wasm/evaluator.go), so each bound preset gets its own linear memory / guest globals with no cross-talk..startwin), resolve wasm-first when the combined bundle provides it (faster per-call), Starlark otherwise — or add awasm:/star:disambiguator.maketarget compiling the bundle under TinyGo (wasi), same lane asbuild-wasm-tinygo.Related
Follow-up from the wasm-visor proxy-reliability work (#3939) and the transport-cost survey (#3941). The Starlark preset comparison is deferred; wasm presets are preferred for per-call speed.