WebAssembly / WebAssembly/wasi-messaging

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

Open
#33 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
No language data
Stars
33
Forks
13
PR merge metrics
No merged PRs in 30d

Description

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.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the 0.2.0-draft incoming-handler WIT interface and the runtime flow calling wasi_messaging_incoming_handler().call_configure(). Determine the intended pattern for declaring guest subscription topics without hard-coding them in the provider, then document or specify the expected configuration behavior and how completion can be verified.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, wasm
Domain
api, distributed-systems
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.