JoinSet: Structured Concurrency
use tokio::task::JoinSet;
let mut set = JoinSet::new();
for i in 0..10 {
set.spawn(async move { expensive_task(i).await });
}
while let Some(result) = set.join_next().await {
match result {
Ok(value) => println!("got: {}", value),
Err(e) => eprintln!("task panicked: {}", e),
}
}
JoinSet::drop() aborts all outstanding tasks — no orphan tasks possible.