Thanks to visit codestin.com
Credit goes to github.com

Skip to content

What is the intended mechanism for an incoming-handler to configure subscription topics? #33

@andrew-goldie

Description

@andrew-goldie

In implementing the 0.2.0-draft WIT I had some problems understanding how to allow a guest subscriber to configure the topics the underlying provider will listen on. I ended up extending the incoming-handler interface thus:

interface incoming-handler {
    use types.{message, error, topic};

    /// Whenever this guest receives a message in one of the subscribed topics, the message is
    /// sent to this handler. The guest is responsible for matching on the topic and handling the
    /// message accordingly. Implementors (such as hosts) calling this interface should make their
    /// own decisions on how to handle errors returned from this function.
    handle: func(message: message) -> result<_, error>;

    /// Server configuration.
    /// 
    /// This can be extended to include other configuration options in the
    /// future.
    record server-configuration {
        /// Subscription topics
        topics: list<topic>,
    }

    /// Configure is called by the runtime to get the server's runtime
    /// configuration.
    configure: func() -> result<server-configuration, error>;
}

A sample guest would look like...

struct MessagingGuest;

impl Guest for MessagingGuest {
    fn handle(msg: Message) -> Result<(), Error> {
        let Some(topic) = &msg.topic() else {
            return Ok(());
        };
        // do stuff conditional on topic
        Ok(())
    }

    fn configure() -> Result<ServerConfiguration, Error> {
        Ok(ServerConfiguration {
            topics: vec!["a", "b", "c", "d"].into_iter().map(|s| s.to_string()).collect(),
        })
    }
}

Then when setting up the component in the runtime our calls look something like...

use wasmtime::Store;
use wasmtime::component::InstancePre;

use crate::messaging::generated::MessagingPre;
//...
    let mut store = Store::new(pre.engine(), Ctx::new(resources.clone(), pre.clone()));
    let msg_pre = MessagingPre::new(pre.clone())?;
    let msg = msg_pre.instantiate_async(&mut store).await?;
    let config = msg.wasi_messaging_incoming_handler().call_configure(&mut store).await??; 

   // Now I can configure NATS subscription subjects, spawn a thread for each message
   // and pass the message (as a resource handle) to the incoming handler's handle function.

Apologies if the code snippets make my simple question more complicated than necessary. All I really want to understand is the intended pattern to ensure the guest only listens to topics it's interested in without hard-coding it into the component.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions