Stream: wasmtime

Topic: async_trait, bindgen! and wasmtime::component


view this post on Zulip Anatolii Smolianinov (Feb 07 2023 at 21:35):

hi, I'm doing my first steps with rust and wasm: want to compile a simple component which can execute an http request. I was looking for a way to pass and object with complex types and came across component model implementation. Seem to be working for me, however, I've stuck with async imports. in docs i've found async option for bindgen! macro, but I'm getting an error while trying to compile:

error[E0706]: functions in traits cannot be declared `async`
  --> src/main.rs:9:1
   |
9  | / wasmtime::component::bindgen!({
10 | |     world: "http",
11 | |     async: true,
12 | | });
   | |__^ `async` because of this
   |
   = note: `async` trait functions are not currently supported
   = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
   = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
   = help: add `#![feature(async_fn_in_trait)]` to the crate attributes to enable
   = note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)

and here is what i see in cargo expand output:

use wasmtime::*;
pub struct Http {
    mainfn: wasmtime::component::Func,
}
pub trait HttpImports {
    async fn request(&mut self, url: String) -> anyhow::Result<String>;
}

so I was confused, because I expected to see some tracks of async_trait there.

I've also tried to enable #![feature(async_fn_in_trait)] but no luck:

error: future cannot be sent between threads safely
  --> src/main.rs:10:1
   |
10 | / wasmtime::component::bindgen!({
11 | |     world: "http",
12 | |     async: true,
13 | | });
   | |__^ future created by async block is not `Send`
   |
   = help: within `[async block@src/main.rs:10:1: 13:3]`, the trait `Send` is not implemented for `impl std::future::Future<Output = std::result::Result<std::string::String, anyhow::Error>>`

src:

wasmtime::component::bindgen!({
    world: "http",
    async: true,
});

impl HttpImports for HttpState {
    async fn request(&mut self, url: String) -> anyhow::Result<String> {
        println!("url is: {}", url);
        Ok(url.clone())
    }
}

async fn eval_with_imported() -> anyhow::Result<String> {
    // Configure an `Engine` and compile the `Component` that is being run for
    // the application.
    let mut config = Config::new();
    config.async_support(true);
    config.wasm_component_model(true);
    let engine = Engine::new(&config)?;
    let component =
        wasmtime::component::Component::from_file(&engine, "../pasm-wit/pasm-wit-component.wasm")?;

    // Instantiation of bindings always happens through a `Linker`.
    // Configuration of the linker is done through a generated `add_to_linker`
    // method on the bindings structure.
    //
    // Note that the closure provided here is a projection from `T` in
    // `Store<T>` to `&mut U` where `U` implements the `HelloWorldImports`
    // trait. In this case the `T`, `MyState`, is stored directly in the
    // structure so no projection is necessary here.
    let mut linker = wasmtime::component::Linker::new(&engine);
    Http::add_to_linker(&mut linker, |state: &mut HttpState| state)?;

    // As with the core wasm API of Wasmtime instantiation occurs within a
    // `Store`. The bindings structure contains an `instantiate` method which
    // takes the store, component, and linker. This returns the `bindings`
    // structure which is an instance of `HelloWorld` and supports typed access
    // to the exports of the component.
    let mut store = Store::new(&engine, HttpState {});
    let (bindings, _) = Http::instantiate_async(&mut store, &component, &linker).await?;

    // Here our `greet` function doesn't take any parameters for the component,
    // but in the Wasmtime embedding API the first argument is always a `Store`.
    let res = bindings.call_mainfn(&mut store).await?;

    Ok(res)
}
A fast and secure runtime for WebAssembly. Contribute to bytecodealliance/wasmtime development by creating an account on GitHub.

view this post on Zulip Alex Crichton (Feb 07 2023 at 22:37):

This looks like the #[async_trait] attribute is getting lost or is accidentally omitted, can you open an issue about this?

view this post on Zulip Anatolii Smolianinov (Feb 07 2023 at 23:20):

oh, I've thought so too but decided to check here.
will do -- thanks!

view this post on Zulip Anatolii Smolianinov (Feb 07 2023 at 23:33):

https://github.com/bytecodealliance/wasmtime/issues/5743

wasmtime::component::bindgen!({ world: "http", async: true, }); impl HttpImports for HttpState { async fn request(&mut self, url: String) -> anyhow::Result<String> { println!...

view this post on Zulip Alex Crichton (Feb 07 2023 at 23:43):

Thanks!

view this post on Zulip Giom (Feb 22 2023 at 23:55):

Unfortunately, I seem to have the same error.
I am using wastime v6.0.0. in this version the error should be fixed or? However, using cargo expand I don't see any #[async_trait] annotation on the trait.

view this post on Zulip bachrc (Feb 23 2023 at 00:06):

Well you just have to add the #[async_trait] before your impl block

view this post on Zulip Giom (Feb 23 2023 at 09:39):

Yes, thats what I did. But still the same.
However, when I use cargo expand, I don't see anything on the trait that can be attributed to a #[async_trait].


Last updated: Dec 23 2024 at 13:07 UTC