golemcloud / wasm-rpc

Apache License 2.0
5 stars 3 forks source link

Support Circular dependency case by inlining the definitions in the stub generator #40

Closed afsalthaj closed 4 months ago

afsalthaj commented 5 months ago

If workers are spawn from the same component, and these workers need to communicate with each other, it ends up in a circular dependency case where in each generated stub which depends on the original wit (from which the stub was generated), becomes a dependency to the original wit.

For example, the original wit here is called timeline-processor.wit and the generated stub will be _stub.wit

# This is the timeline-processor.wit

package timeline:timeline-processor;

interface api {
  record foo {
    value: string
  }

  initialize: func(start: foo) -> string;
}

world timeline-processor {
  export api;
}

The corresponding generated stub wit will be (obviously)

# this is the generated stub wit which comes under the generated stub module timeline-processor-stub
package timeline:timeline-processor-stub;

interface stub-timeline-processor {
  use golem:rpc/types@0.1.0.{uri};
  use timeline:timeline-processor/api.{foo};

  resource api {
    constructor(location: uri);
    initialize: func(start: foo) -> string;
  }

}

world wasm-rpc-stub-timeline-processor {
  export stub-timeline-processor;
}

Now we add this stub as dependency to timeline-processor itself (because we need the communication between workers that were spawned from timeline-processor template)

However whe using the current golem-cli stubgen add-stub-dependency (0.62 version), we end up having timeline_processor.wit along with _stub.wit into the wit dependencies of timeline-processor itself, making it a redundant circular dependency.

The subsequent cargo component build will result in the following error

thread 'main' panicked at /Users/afsalthaj/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wit-parser-0.13.1/src/resolve.rs:1034:9:
assertion failed: prev.is_none()
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Solution

The solution is to basically inline the definitions in the original wit (timeline_processor.wit) into the _stub.wit that is under wit/deps in timeline-processor.

i.e,

# stub.wit

package timeline:timeline-processor-stub;

interface stub-timeline-processor {
  use golem:rpc/types@0.1.0.{uri};

  record foo {
    value: string
  }

  resource api {
    constructor(location: uri);
    initialize: func(start: foo) -> string;
  }

}

world wasm-rpc-stub-timeline-processor {
  export stub-timeline-processor;
}

And thereby, not ending up having to paste timeline-processor.wit itself in wit/deps, and things will compile

sameerparekh commented 4 months ago

Thanks for getting on this! I am trying to do a big refactor right now and having this working will be a big help. I built wasm-rpc-stubgen from the latest git sha, and I'm running into this problem:

When I run cargo make build-flow I see this:

cargo make build-flow
[cargo-make] INFO - cargo make 0.36.3
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build-flow
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Execute Command: "cargo-component" "clean"
error: failed to create a target world for package `accountant` (/Users/sameer/workspace/sputnik/accountant/Cargo.toml)

Caused by:
    0: failed to read content of dependency `sputnik:accountant-stub` at path `/Users/sameer/workspace/sputnik/accountant/wit/deps/sputnik_accountant-stub`
    1: No such file or directory (os error 2)

Stack backtrace:
   0: std::backtrace::Backtrace::create
   1: cargo_component_core::registry::DependencyResolution::decode
   2: cargo_component::bindings::BindingsGenerator::create_target_world
   3: cargo_component::bindings::BindingsGenerator::new
   4: cargo_component::run_cargo_command::{{closure}}
   5: cargo_component::main::{{closure}}
   6: tokio::runtime::park::CachedParkThread::block_on
   7: tokio::runtime::context::runtime::enter_runtime
   8: tokio::runtime::runtime::Runtime::block_on
   9: cargo_component::main
  10: std::sys_common::backtrace::__rust_begin_short_backtrace
  11: std::rt::lang_start::{{closure}}
  12: std::rt::lang_start_internal
  13: _main
[cargo-make] ERROR - Error while executing command, exit code: 1
[cargo-make] WARN - Build Failed.

and when I run cargo make generate-accountant-stub:

cargo make generate-accountant-stub
[cargo-make] INFO - cargo make 0.36.3
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: generate-accountant-stub
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Execute Command: "wasm-rpc-stubgen" "generate" "-s" "accountant/wit" "-d" "accountant-stub"
Error: Failed to gather information for the stub generator. Make sure source_wit_root has a valid WIT file.

Caused by:
    failed to find package `sputnik:accountant-stub` in `deps` directory

Stack backtrace:
   0: std::backtrace::Backtrace::capture
   1: anyhow::error::<impl anyhow::Error>::msg
   2: anyhow::__private::format_err
   3: golem_wasm_rpc_stubgen::stub::visit
   4: golem_wasm_rpc_stubgen::stub::get_unresolved_packages
   5: golem_wasm_rpc_stubgen::stub::StubDefinition::new
   6: golem_wasm_rpc_stubgen::generate
   7: wasm_rpc_stubgen::main
   8: std::sys_common::backtrace::__rust_begin_short_backtrace
   9: _main
[cargo-make] INFO - Build Done in 1.04 seconds.

accountant/wit does have a valid accountant.wit file in it of course.

I pushed a PR that has my relevant changes but it seems like I have some other changes mixed in by mistake. Will update with a clean PR once I've cleaned that up.

I'm wondering if this is because

1) x->y->x is still not working, or 2) I did the manual inlining of the dependencies and that doesn't work with the automatic inlining in this change?

I will continue to investigate as I have time. Thanks!

sameerparekh commented 4 months ago

I've fixed up and cleaned the PR, it is here: https://github.com/sameerparekh/sputnik-golem/pull/18

I ran cargo make build-flow with this PR and saw the is_none() error, and it generated the latest commit in that PR.

Writing updated Cargo.toml to "adminapi/Cargo.toml"
[cargo-make] INFO - Execute Command: "wasm-rpc-stubgen" "generate" "-s" "accountant/wit" "-d" "accountant-stub"
thread 'main' panicked at /Users/sameer/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wit-parser-0.201.0/src/resolve.rs:1169:9:
assertion failed: prev.is_none()
stack backtrace:
   0:        0x10440dbc4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h01b2beffade888b2
   1:        0x104233e40 - core::fmt::write::hbadb443a71b75f23
   2:        0x1043e4970 - std::io::Write::write_fmt::hc09d7755e3ead5f0
   3:        0x10440f3a4 - std::sys_common::backtrace::print::h28349e5c25acbac7
   4:        0x10440ecf0 - std::panicking::default_hook::{{closure}}::hd24b6196784d991e
   5:        0x10440e8bc - std::panicking::default_hook::hfcec80a2720c8c73
   6:        0x10440fc00 - std::panicking::rust_panic_with_hook::h84760468187ddc85
   7:        0x10440f67c - std::panicking::begin_panic_handler::{{closure}}::he666a5eb600a7203
   8:        0x10440f60c - std::sys_common::backtrace::__rust_end_short_backtrace::h592f44d2bf9f843f
   9:        0x10440f600 - _rust_begin_unwind
  10:        0x1047bb258 - core::panicking::panic_fmt::h98bbf7bdf4994454
  11:        0x1047bb30c - core::panicking::panic::hc59c8a709a9b37ae
  12:        0x10478e5c4 - wit_parser::resolve::Remap::append::h8883edd716b5455f
  13:        0x104788bd4 - wit_parser::resolve::Resolve::push::h794ecd84927c124b
  14:        0x1042abf58 - golem_wasm_rpc_stubgen::stub::StubDefinition::new::ha94fd859acee088e
  15:        0x10428d684 - golem_wasm_rpc_stubgen::generate::hd262537a0745b065
  16:        0x104592694 - wasm_rpc_stubgen::main::h2c0d3796d22ec25b
  17:        0x104599e10 - std::sys_common::backtrace::__rust_begin_short_backtrace::h3c3a63c56fb8d854
  18:        0x1045910c8 - _main
[cargo-make] ERROR - Error while executing command, exit code: 101
[cargo-make] WARN - Build Failed.

running a second time gives me the same error but this time at the clean step:

cargo make build-flow
[cargo-make] INFO - cargo make 0.36.3
[cargo-make] INFO - Build File: Makefile.toml
[cargo-make] INFO - Task: build-flow
[cargo-make] INFO - Profile: development
[cargo-make] INFO - Running Task: legacy-migration
[cargo-make] INFO - Execute Command: "cargo-component" "clean"
  Generating bindings for adminapi (/Users/sameer/workspace/sputnik/adminapi/src/bindings.rs)
thread 'main' panicked at /Users/sameer/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wit-parser-0.13.1/src/resolve.rs:1034:9:
assertion failed: prev.is_none()
stack backtrace:
   0:        0x102d98ee4 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hb478ebbfb46e27ce
   1:        0x102dba100 - core::fmt::write::he4d5fa2daff1f531
   2:        0x102d95410 - std::io::Write::write_fmt::hc5a47a68eba63d9f
   3:        0x102d98d18 - std::sys_common::backtrace::print::h79bd952cc5812e7a
   4:        0x102d9a4c0 - std::panicking::default_hook::{{closure}}::h82301f6222887737
   5:        0x102d9a208 - std::panicking::default_hook::h1e49abbb3f1d7dbf
   6:        0x102d9a908 - std::panicking::rust_panic_with_hook::h1e70c5d905e30e9d
   7:        0x102d9a7d0 - std::panicking::begin_panic_handler::{{closure}}::h399e32952efd26a4
   8:        0x102d99368 - std::sys_common::backtrace::__rust_end_short_backtrace::h2ab87f841a2323e7
   9:        0x102d9a584 - _rust_begin_unwind
  10:        0x102e23d2c - core::panicking::panic_fmt::h33e40d2a93cab78f
  11:        0x102e23db4 - core::panicking::panic::h57fd475c037a9df3
  12:        0x102b0f3bc - wit_parser::resolve::Remap::append::hf0a4902c2e5efeb3
  13:        0x102b216fc - wit_parser::ast::SourceMap::rewrite_error::h411a009861a15487
  14:        0x102b0385c - wit_parser::resolve::Resolve::push::h1a01cae65197fed0
  15:        0x10287ea04 - cargo_component::bindings::BindingsGenerator::create_target_world::h64849129f3cc8b9b
  16:        0x10287aa54 - cargo_component::bindings::BindingsGenerator::new::h6efaa1a2ada9b9d3
  17:        0x10269bcc4 - cargo_component::run_cargo_command::{{closure}}::h9a627e9877ab8633
  18:        0x1026b0dac - cargo_component::main::{{closure}}::hb955c16fd1ace6a5
  19:        0x1026ab4e0 - tokio::runtime::park::CachedParkThread::block_on::ha1b8d054c8f2a772
  20:        0x102798ffc - tokio::runtime::context::runtime::enter_runtime::hea8bb7e9fd218a77
  21:        0x10276adf0 - tokio::runtime::runtime::Runtime::block_on::h5494f2a473f673da
  22:        0x102743dcc - cargo_component::main::h4b2437b0e35f78b7
  23:        0x102758844 - std::sys_common::backtrace::__rust_begin_short_backtrace::h322ab5ba4fd90cb7
  24:        0x10276f544 - std::rt::lang_start::{{closure}}::h99915cb0bfc2b2bb
  25:        0x102d8d58c - std::rt::lang_start_internal::hf4f3eb1e51305b96
  26:        0x102743ed4 - _main
[cargo-make] ERROR - Error while executing command, exit code: 101
[cargo-make] WARN - Build Failed..