Understanding mpsc::channel that's needed for Iced subscriptions

I wrote a new subscription for my Iced application that opens a network connection to a server and sends messages when there is new data available. I use Sender::send, which returns a Future that resolves to a Result. While developing, I simply unwrapped all the results because I wasn’t sure under what circumstances could it fail. I now want to understand that and improve my code, so I’m trying to write a minimal function that exemplifies overflowing the receiver with many messages, here’s my first idea:

use iced::futures::SinkExt;
use iced::futures::channel::mpsc::channel;
#[tokio::main]
async fn main() {
    let (mut sender, receiver) = channel::<bool>(0);
    sender.send(true).await.unwrap();
    sender.send(true).await.unwrap();
}

This hangs, however, as the first send won’t resolve until the receiver process the message, which I don’t do here.

So, I try to have the two tasks run asynchronously.

use iced::futures::SinkExt;
use iced::futures::channel::mpsc::channel;
#[tokio::main]
async fn main() {
    let (mut sender, receiver) = channel::<bool>(0);
    iced::futures::join!(
        sender.send(true),
        sender.send(true),
    );
}

But this doesn’t compile because sender cannot be borrowed mutably twice.

Then I resort to having two senders.

use iced::futures::SinkExt;
use iced::futures::channel::mpsc::channel;
#[tokio::main]
async fn main() {
    let (mut sender, receiver) = channel::<bool>(0);
    let mut sender2 = sender.clone();
    iced::futures::join!(
        sender.send(true),
        sender2.send(true),
    );
}

This hangs as well because the receiver has an implicit capacity set by the number of senders, so it’s not really full.

How can a recreate a scenario where the receiver gets full?

An mpsc channel provides backpressure. In other words, sending will wait until there is capacity.

You can always use try_send if you want to skip the backpressure mechanism.

In other words, send will only really fail if the Receiver is dropped or closed.

In other words, send will only really fail if the Receiver is dropped or closed.

Ah, of course, it seems obvious now but I didn’t think about this case. I assume this would never happen during the lifetime of an Iced application so it’s not worth handling it, right?

Thanks.