I'm wondering, whether handling a tokio::task::JoinHandle like this could ever panic:
#[tokio::main]
async fn main() {
let pool = tokio_util::task::LocalPoolHandle(1);
let join_handle = pool.spawn_pinned(my_task()).await;
if join_handle.is_cancelled() {
unreachable!("because we await the result above")
}
// Never panics because the task is guaranteed to not be canceled:
let _err = join_handle.into_panic();
}
I assume the above is safe to do, but I couldn't find any definite information about when a task spawned via a LocalPoolHandle would be canceled (besides me calling join_handle.abort(), which I don't do).
If the above task can be canceled somehow, I need to add a Canceled variant to my error enum, which I'd like to avoid if the task can't be canceled.
my_task() could be anything, so I cannot make any assumptions about what happens there.
The types don't work out. LocalPoolHandle::spawn_pinned() returns Result<Future::Output, JoinError>, so unless you've got an error (i.e., the task panicked), you can't even get to a type that implements an is_cancelled() methods.
Could you post some code that actually compiles? It'd be much easier to answer if we didn't have to second guess you.
Sorry about that (I shouldn't post when I'm under time pressure).
Here is a snipped that actually compiles:
#[tokio::main]
async fn main() {
let pool = tokio_util::task::LocalPoolHandle::new(1);
let Err(join_error) = pool.spawn_pinned(|| async { () }).await else {
return
};
if join_error.is_cancelled() {
unreachable!("because we await the result above")
}
// Never panics because the task is guaranteed to not be canceled:
let err = join_error.into_panic();
dbg!(err);
}