Stream: wasmtime

Topic: Problems migrating to wasmtime 29.0.0


view this post on Zulip Richard Backhouse (Jan 21 2025 at 13:30):

I'm trying to migrate my app to wasmtime 29.0.0 and am hitting a compile error for the Host implementations I have.

For one of them I have a wit that looks like this

interface evt {
    enum event-type {
        info,
        warning,
        error,
        debug,
    }
    emit-event: func(et: event-type, event-name: string, event-data: list<u8>);
}

world event {
    import evt;
}

And the Host code using the bindgen macro looks like this

wasmtime::component::bindgen!({
    path: "../../wit/event",
    world: "event",
    async: true,
});

pub enum EventType {
    Info,
    Warning,
    Error,
    Debug,
}

pub struct EventManagerCtx {
    eventmanager: Box<dyn EventManager + std::marker::Send>
}

impl EventManagerCtx {
    pub fn new(eventmanager: Box<dyn EventManager + std::marker::Send>) -> anyhow::Result<Self> {
        Ok(EventManagerCtx {
            eventmanager: eventmanager
        })
    }
}

#[async_trait::async_trait]
pub trait EventManager {
    async fn emit_event(&mut self, et: EventType, event_name: String, event_data: Vec<u8>) -> ();
}

#[async_trait::async_trait]
impl airedale::event::evt::Host for EventManagerCtx {
    async fn emit_event(&mut self, et:airedale::event::evt::EventType, event_name:String, event_data:Vec<u8>,) -> () {
        let event_type: EventType;
        match et {
            airedale::event::evt::EventType::Info => event_type = EventType::Info,
            airedale::event::evt::EventType::Warning => event_type = EventType::Warning,
            airedale::event::evt::EventType::Debug => event_type = EventType::Debug,
            airedale::event::evt::EventType::Error => event_type = EventType::Error,
        }

        self.eventmanager.emit_event(event_type, event_name, event_data).await;
    }
}

pub trait EventManagerFactory {
    fn new_eventmanager(&mut self) -> Box<dyn EventManager + std::marker::Send>;
}

With 29.0.0 I'm now getting an error on the emit_event function

error[E0195]: lifetime parameters or bounds on method `emit_event` do not match the trait declaration
  --> crates/airedale-container/src/event.rs:33:14
   |
5  | });
   |   - lifetimes in impl do not match this method in trait
...
31 | #[async_trait::async_trait]
   | --------------------------- this `where` clause might not match the one in the trait
32 | impl airedale::event::evt::Host for EventManagerCtx {
33 |     async fn emit_event(&mut self, et:airedale::event::evt::EventType, event_name:String, event_data:Vec<u8>,) -> () {
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait

I took a look at comparing the generated code and see that

            #[wasmtime::component::__internal::async_trait]

was removed in the 29.0.0 version and replaced with

            #[wasmtime::component::__internal::trait_variant_make(::core::marker::Send)]

Any thoughts on how to fix this ?
Thanks

view this post on Zulip Victor Adossi (Jan 21 2025 at 14:03):

Just a guess but I think this is coming from a vendored version of the trait-variant crate that is now in use by wasmtime to ensure that the Send bound is present on the Self in question.

In your example the EventManagerCtx contains a Box<T> which is only Send when the internal type (dyn T in this case) is Send, and that's not the case by default -- You likely need to change to using a Box<dyn T + Send> to restrict what can be put in the Box to be Send (which should then then trigger the auto-implementation of Send for Box<T>).

view this post on Zulip Richard Backhouse (Jan 21 2025 at 15:31):

I guess I'm not following. The EventManagerCtx already has the Box<dyn T + Send>.

pub struct EventManagerCtx {
    eventmanager: Box<dyn EventManager + std::marker::Send>
}

It looks like this pr removed async_trait from bindgen

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

Feature Remove the use of async_trait in bindgen! as per #9776 (comment). Use async fn in traits, RPITIT and trait_variant instead. Benefit Removing async_trait simplifies the generated code by bin...

view this post on Zulip Victor Adossi (Jan 21 2025 at 15:51):

Ah sorry I could have sworn it only said Box<dyn EventManager>...

Did you try removing the async_trait annotation and using the built in async w/ return position impl Trait? This is where the trait_variant recommendation comes from (at least that's where I saw it)

Empowering everyone to build reliable and efficient software.

Last updated: Jan 24 2025 at 00:11 UTC