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?
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}");
});
}
2 Likes
Everything in tokio::sync
is executor independent.
4 Likes