Hello everyone,
I've been trying to use wasm-tools compose
to combine WebAsembly Components together, but having some trouble getting config.yml
to give me a single instantiation for a shared state.
Say there's a count
that is stored in a common component, with an increment
and show
component, which are composed together in an aggregate
component.
The idea is to verify that both paths show the same state. Right now with the way I'm composing them, it looks like I have two different instantiations?
I've got a reproducable, testable example here
search-paths:
- ./target/was32-wasi/release
dependencies:
increment:increment/increase@0.1.0: ./target/wasm32-wasi/debug/increment.wasm
shower:show/display@0.1.0: ./target/wasm32-wasi/debug/show.wasm
counter:count/change@0.1.0: ./target/wasm32-wasi/debug/count.wasm
counter:count/current@0.1.0: ./target/wasm32-wasi/debug/count.wasm
instantiations:
root:
arguments:
increment:increment/increase@0.1.0: increment
shower:show/display@0.1.0: show
increment:
arguments:
counter:count/change@0.1.0: counter
show:
arguments:
counter:count/current@0.1.0: counter
The Ask: What does the config.yml
need to look like in order for there to be just 1 count
component instance? I've tried a bunch of combinations but can't seem to get a single instance of the shared state.
Note that we get 1 instance with 1 interface (works as expected) but 2 instance with 2 interfaces to the same dependency.
So I should clarify: What config do we need in order to get 1 instance from 2 different interfaces from the same .wasm
file?
Give this config a try:
dependencies:
increment: ./target/wasm32-wasi/debug/increment.wasm
show: ./target/wasm32-wasi/debug/show.wasm
counter: ./target/wasm32-wasi/debug/count.wasm
instantiations:
root:
arguments:
increment:increment/increase@0.1.0: increment
shower:show/display@0.1.0: show
increment:
arguments:
counter:count/change@0.1.0: counter
show:
arguments:
counter:count/current@0.1.0: counter
There should be one dependency entry per component wasm so that you don't end up with duplicated components in the composition.
Very soon there will be a new language for composing (and virtualizing) components that's actively in development, so the above might look like this:
let counter = new counter:count { ... };
let shower = new shower:show { current: counter.current, ... };
let increment = new increment:increment { change: counter.change, ... };
let aggregate = new aggregate:aggregate { display: shower.display, increase: increment.increase, ... };
export aggregate.controls;
hopefully that makes it much clearer in terms of how many instances there are and how they're wired up (note: the ...
syntax means "fill in the blanks with shared imports from the composed component")
Thanks @Peter Huene ! Since there's a new config language on the way soon, no need to spend precious time on the old one. Looking forward to checking out the new language.
Hi @Peter Huene,
I know the new language is coming, but I thought I'd pass back some feedback I got after I apply that suggested config. It errors with:
$ wasm-tools compose --config config.yml --output aggregate.wasm target/wasm32-wasi/debug/aggregate.wasm
instance `increment:increment/increase@0.1.0` will be imported because
a dependency named `increment:increment/increase@0.1.0` could not be found
instance `shower:show/display@0.1.0` will be imported because
a dependency named `shower:show/display@0.1.0` could not be found
error: no dependencies of component `target/wasm32-wasi/debug/aggregate.wasm` were found
I think this has something to do with the naming of the dep handle? It seems to want the name to be the same as the dep itself.
Reproduction is here: https://github.com/DougAnderson444/compose-example/blob/master/config.yml
Hi @DougAnderson444 | PeerPiper.io. Sorry for the delayed response!
When I now clone your repo, switch to a nightly Rust, and do:
cargo component build
wasm-tools compose -c config.yml target/wasm32-wasi/debug/aggregate.wasm -t
I get a composed component and looking over it, I see instance 10 (counter) being shared between the instances for increment and show.
I'm not running into the issue you are for some reason.
By the way, there's new syntax in wac that makes the alternative example even easier:
package composed:component;
let counter = new counter:count { ... };
let shower = new shower:show { ...counter, ... };
let increment = new increment:increment { ...counter, ... };
let aggregate = new aggregate:aggregate { ...shower, ...increment, ... };
export aggregate...;
The ...<instance>
syntax in the instantiation arguments "spreads" the exports of the instance to any matching instantiation args and the <expr>...
syntax in the export statement "spreads" the exports of the expression (just aggregate
in this case) as exports of the composed component.
You'd encode the above with:
wac encode composition.wac --define -d counter:count=target/wasm32-wasi/debug/count.wasm -d shower:show=target/wasm32-wasi/debug/show.wasm -d increment:increment=target/wasm32-wasi/debug/increment.wasm -d aggregate:aggregate=target/wasm32-wasi/debug/aggregate.wasm > output.wasm
in the future where a component registry exists, those -d
options would disappear and the tool would just fetch them from the registry (client support already exists in wac, but there's no registry servers available just yet)
"It's not you, it's me."
I must have had too old of a version of wasm-tools
or rust
, after updating both, switching to nightly
, it compiles and tests pass. This is great! It works!
Thanks for your help @Peter Huene! How long before we use the new wac
language?
Also I want to just thank you in general -- this Component Model is so cool, I'm really looking forward to building some neat tech with it!
Thanks for your help @Peter Huene! How long before we use the new wac language?
You can use it today if you install it directly from https://github.com/peterhuene/wac, but I hope on integrating it into wasm-tools compose
sooner than later.
Last updated: Dec 23 2024 at 12:05 UTC