Problem with using async-global-executor

use async_channel::unbounded as channel;
use async_global_executor::{spawn, block_on};

fn main() {
    block_on(async {
        let (tx, rx) = channel();

        let _ = spawn(async move {
            println!("sub process");
            tx.send(()).await.unwrap();
            println!("sent");
        });

        println!("main process");
        rx.recv().await.unwrap();
        println!("received");
    });
}

expected

sub process
sent
main process
received

result

main process
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: RecvError', main.rs:15:25

Similar code on tokio works well.

use tokio::{sync::mpsc::unbounded_channel as channel, spawn};

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

    let _ = spawn(async move {
        println!("sub process");
        tx.send(()).unwrap();
        println!("sent");
    });

    println!("main process");
    rx.recv().await.unwrap();
    println!("received");
}
main process
sub process
sent
received

The documentation says:

Dropping a Task cancels it, which means its future won’t be polled again. To drop the Task handle without canceling it, use detach() instead.

Thus, let _ = spawn immediately cancels the sending task. This is different from Tokio, where detaching is the default behavior.

When you encounter surprising behavior, try reading the documentation of all the functions and types you are using, even if you think you know how they work — there is often a detail that matters.

1 Like

Just careless ... Sorry...