zesterer / flume

A safe and fast multi-producer, multi-consumer channel.
https://crates.io/crates/flume
Apache License 2.0
2.43k stars 84 forks source link

async selector #133

Closed vortex314 closed 1 year ago

vortex314 commented 1 year ago

Maybe a dumb question as I just started in Rust. I notice that the selector .wait () isn't a future or async in itself. Is it possible to do an async selection on different channels ? A sample code below on which I wanted to create a async selection. Do I need to use an executor ?

use std::{thread, sync::Arc};

use flume::{Receiver, Selector, Sender};
use futures::executor::block_on;

struct Source {
    timer_on: Receiver<()>,
    timer_trigger: Sender<()>,
    event_tx: Sender<()>,
    event_rx: Receiver<()>,
    result_tx: Sender<()>,
    result_rx: Receiver<()>,
}

impl Source {
    fn new() -> Self {
        let (tx, rx) = flume::unbounded();
        let (event_tx, event_rx) = flume::unbounded();
        let (result_tx, result_rx) = flume::unbounded();

        Source {
            timer_trigger: tx,
            timer_on: rx,
            event_tx,
            event_rx,
            result_tx,
            result_rx,
        }
    }

    fn trigger(&self) {
        self.timer_trigger.send(()).unwrap();
    }

    fn event(&self) {
        self.event_tx.send(()).unwrap();
    }

    fn result(&self) -> Receiver<()> {
        self.result_rx.clone()
    }

    async fn run(&self) -> () {
        loop {
            Selector::new()
                .recv(&self.timer_on, |_| {
                    println!("timer_on");
                    self.result_tx.send(()).unwrap();
                })
                .recv(&self.event_rx, |_| println!("event"))
                .wait();
        }
    }
}

fn main() {
    println!("Flume test");
    let source = Arc::new(Source::new());
    source.trigger();
    source.event();
    let src = source.clone();
    let handle = thread::spawn(move || {
        block_on(src.run());
    });
    println!("{:?}",source.result().recv().unwrap());
    handle.join().unwrap();
}
Restioson commented 1 year ago

You can do this by just selecting the futures themselves - for example, https://docs.rs/futures/latest/futures/macro.select.html. Let me know if you have any further queries!

vortex314 commented 1 year ago

Thanks for the help ! Works as expected now.