Channels across runtimes?

Is it legal in tokio to have channels that span runtimes? That is, in an application with two tokio runtimes, can the receiving and sending end of one of the channels in tokio::sync live in those separate runtimes?

Yes.

2 Likes

Thanks. There's no note but I assume the same is true for one shot channels, etc.

Yeah I'd say so. I wrote a crude little test where I put the sender and receiver in two different runtimes and pass messages between those runtimes with mpsc, oneshot and broadcast channels. All messages are sent and received:

use tokio::sync;

fn main() {
    // mpsc
    let (tx, mut rx) = sync::mpsc::channel::<u8>(1);
    
    let rt_tx = tokio::runtime::Runtime::new().unwrap();
    let rt_rx = tokio::runtime::Runtime::new().unwrap();
    
    rt_tx.block_on(async move {
        let val = 0;
        tx.send(val).await.unwrap();
        println!("send mpsc message: {val}");
    });
    
    rt_rx.block_on(async move {
        let val = rx.recv().await.unwrap();
        println!("received mpsc message: {val}");
    });
    
    // oneshot
    let (tx, rx) = sync::oneshot::channel::<u8>();

    let rt_tx = tokio::runtime::Runtime::new().unwrap();
    let rt_rx = tokio::runtime::Runtime::new().unwrap();
    
    rt_tx.block_on(async move {
        let val = 1;
        tx.send(val).unwrap();
        println!("send oneshot message: {val}");
    });
    
    rt_rx.block_on(async move {
        let val = rx.await.unwrap();
        println!("received oneshot message: {val}");
    });
    
    // broadcast
    let (tx, mut rx) = sync::broadcast::channel::<u8>(1);
    
    let rt_tx = tokio::runtime::Runtime::new().unwrap();
    let rt_rx = tokio::runtime::Runtime::new().unwrap();
    
    rt_tx.block_on(async move {
        let val = 2;
        tx.send(val).unwrap();
        println!("send broadcast message: {val}");
    });
    
    rt_rx.block_on(async move {
        let val = rx.recv().await.unwrap();
        println!("received broadcast message: {val}");
    });
}

Playground.

2 Likes

Everything in tokio::sync is executor independent.

4 Likes