Stream: wit-bindgen

Topic: Help with `wasm-compose` config.yml


view this post on Zulip DougAnderson444 | PeerPiper.io (Dec 30 2023 at 05:32):

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?

image.png

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.

wasm-compose with shared state. Contribute to DougAnderson444/compose-example development by creating an account on GitHub.

view this post on Zulip DougAnderson444 | PeerPiper.io (Dec 31 2023 at 12:50):

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?

view this post on Zulip Peter Huene (Dec 31 2023 at 18:25):

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

view this post on Zulip Peter Huene (Dec 31 2023 at 18:28):

There should be one dependency entry per component wasm so that you don't end up with duplicated components in the composition.

view this post on Zulip Peter Huene (Dec 31 2023 at 18:34):

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;

view this post on Zulip Peter Huene (Dec 31 2023 at 18:36):

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")

view this post on Zulip DougAnderson444 | PeerPiper.io (Jan 01 2024 at 12:17):

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.

view this post on Zulip DougAnderson444 | PeerPiper.io (Jan 09 2024 at 16:43):

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

view this post on Zulip Peter Huene (Jan 15 2024 at 23:37):

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.

view this post on Zulip Peter Huene (Jan 15 2024 at 23:40):

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.

WebAssembly Composition (WAC) tooling. Contribute to peterhuene/wac development by creating an account on GitHub.

view this post on Zulip Peter Huene (Jan 15 2024 at 23:44):

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

view this post on Zulip Peter Huene (Jan 15 2024 at 23:45):

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)

view this post on Zulip DougAnderson444 | PeerPiper.io (Jan 16 2024 at 18:00):

"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?

view this post on Zulip DougAnderson444 | PeerPiper.io (Jan 16 2024 at 18:01):

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!

view this post on Zulip Peter Huene (Jan 16 2024 at 19:40):

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.

WebAssembly Composition (WAC) tooling. Contribute to peterhuene/wac development by creating an account on GitHub.

Last updated: Dec 23 2024 at 12:05 UTC