Home > database >  How should I respond to a channel message?
How should I respond to a channel message?

Time:05-27

Right now I have a background thread that I'm communicating with using a channel. The details aren't important but I have an enum Message with a variant Variant(Data, Sender<Response>), so that in the background thread I can do:

loop {
    match message_rx.recv() {
        Ok(Message::Variant(data, sender)) => {
            let result = do_something(data);
            sender.send(result);
        }
    }
}

And in the foreground thread(s),

let (response_rx, response_tx) = flume::bounded(1);
message_tx.send(Message::Variant(data, response_tx));
let response = response_rx.recv();

This solution is not concurrent (nor is concurrency a particular goal here) but is it in fact a solution? I was inspired by the Erlang pattern where a process sends its pid with a message so it can receive a response.

CodePudding user response:

It is indeed a pattern, as in your example, embedding a reply communication channel within the message is a good way of doing it,

You can find different utilities for it, for example in an asynchronous environment using tokio, you could use oneshot, which is a channel that ensures a single message, from the example:

use tokio::sync::oneshot;

#[tokio::main]
async fn main() {
    let (tx, rx) = oneshot::channel();

    tokio::spawn(async move {
        if let Err(_) = tx.send(3) {
            println!("the receiver dropped");
        }
    });

    match rx.await {
        Ok(v) => println!("got = {:?}", v),
        Err(_) => println!("the sender dropped"),
    }
}
  • Related