How to use tokio::select! with receiver's recv_many?

Hi, If I use tokio::select! on a mpsc::receiver's recv_many method, does it block until the limit messages received?

For example in below sample code:

use tokio::sync::mpsc;

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

    tx.send("hello").await.unwrap();
    tx.send("world").await.unwrap();

    let mut buffer = Vec::new();
    let limit = 100_usize;
    tokio::select! {
        _ = rx.recv_many(&mut buffer, limit) => {
            println!("Received message!");
        }
    }
}

I'm confused when reading the doc: Receiver in tokio::sync::mpsc - Rust.

In my understanding, if I simply write code without tokio::select!:

let received = rx.recv_many(&mut buf, limit);

It will block until received 100 messages (i.e. the limit number).

If I use tokio::select! on it, does it immediately returns even there's just 1 message?

No, it will receive up to limit many messages and append them to the buffer, not wait till there are limit many messages to receive:

For limit > 0, if there are no messages in the channel’s queue, but the channel has not yet been closed, this method will sleep until a message is sent or the channel is closed.

This behaviour does not change when used in a select! branch and the method is cancellation safe, so you don't need to worry about messages being dropped if another branch finishes first. The method's return value is the number of received messages 0 <= return value <= limit.

4 Likes

thanks, after read it again, I think I understand now (the root cause should be my English reading...)

I find the example to be quite helpful. It illustrates the behaviour of recv_many well IMO, although if limit = 2 would've been used in every call to recv_many, I think it would be clearer that the method does not wait till limit many messages are received.

1 Like

I kind of regret adding recv_many. It's too confusing.

4 Likes

BTW, does recv_many has better performance than recv when there are too many messages pending in channel? i.e. batch processing reduce some contexts switch inside tokio?

Yes it should perform slightly better.

1 Like

thank you for confirm