I'm having trouble understanding the interaction between tokio::try_run!
and tasks running inside tokio::spawn
returning an Err
.
When I run the following sample:
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let h1 = tokio::spawn(async {
sleep(Duration::from_millis(100)).await;
// 1/0; commented for now
let v: Result<i32, ()> = Err(());
v
});
let h2 = tokio::spawn(async {
sleep(Duration::from_millis(500)).await;
println!("h2 didn't get canceled");
let v: Result<i32, ()> = Ok(2);
v
});
match tokio::try_join!(h1, h2) {
Ok((first, second)) => {
println!("try_join was successful, got {:?} and {:?}", first, second);
}
Err(err) => {
println!("try_join had an error: {:?}", err);
}
}
}
it prints
h2 didn't get canceled
try_join was successful, got Err(()) and Ok(2)
However, I expected it to print something like what happens with I uncomment the division by zero inside h1:
thread 'tokio-runtime-worker' panicked at 'attempt to divide by zero', src/bin/select-test.rs:7:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
try_join had an error: JoinError::Panic(...)
The try_join!
docs say
The try_join! macro returns when all branches return with Ok or when the first branch returns with Err.
However, on the example that I posted, h1 does return Err
but try_join!
executes the Ok
variant., Further, h2 doesn't get cancelled, it runs to completion even though h1 had already failed hundreds of miliseconds before. I can't understand if this is contradicting the docs or not. Also, I can't seem to be able to achieve what I was trying to do, which was to get h2 to be canceled when h1 returns Err
.
After more trial and error, I found that when I remove the tokio::spawn
from both h1 and h2, try_join!
does execute in the way I expected and calls the Err
variant. Still, I don't understand why this makes a difference.
Can anyone provide a bit more info into why this is the behavior? Do I need to remove tokio::spawn
and forfeit parallel execution between h1 and h2 if I want h2 to be canceled when h1 returns an error?