Stream: cargo-component

Topic: bidirectional component composition


view this post on Zulip Leon Thomm (Jan 03 2024 at 13:02):

Hey :wave: I am exploring component composition following the component model docs, using cargo component and wasm-tools compose. While the tutorial (calculator component consumes an adder component) matches my understanding, I'm struggling to do the same when both components import from and export to the other respectively. Example:

interface.wit

interface a-to-b {
    foo-AB: func() -> u32;
}

interface b-to-a {
    foo-BA: func() -> u32;
}

interface a-ext {
    entry: func() -> u32;
}

world A {
    import b-to-a;
    export a-to-b;
    export a-ext;
}

world B {
    import a-to-b;
    export b-to-a;
}

with simple implementations

// implementation of A.entry
    fn entry() -> u32 { foo_ba() }

// implementation of A.foo-ab
    fn foo_ab() -> u32 { 42 }

// implementation of B.foo-ba
    fn foo_ba() -> u32 { foo_ab() }

compiled with cargo component build --release, composed with

$ wasm-tools compose A.wasm -d B.wasm -d A.wasm -o composed.wasm

I expected a component which exports only a-ext (with entry returning 42) and no imports. However, the resulting components interface is

package root:component;

world root {
  import test-interface:api/a-to-b;

  export test-interface:api/a-to-b;
  export test-interface:api/a-ext;
}

What am I missing?

view this post on Zulip Joel Dice (Jan 03 2024 at 16:29):

wasm-compose does not currently support circular dependencies, so what you're trying to do is not (yet) possible. In theory, wasm-compose could be modified to support such things using e.g. a synthesized module with indirect function calls to "break" the cycle, but nobody has started working on that AFAIK.


Last updated: Nov 25 2024 at 19:03 UTC