Is it even possible?
I have the following code example:
fn call() -> JoinHandle<()> {
println!("Something");
task::spawn(dos())
}
async fn dos() {
for i in 0..10 {
time::sleep(Duration::from_millis(2000)).await;
println!("in task {}", i);
}
}
async fn run() {
let jh = call();
let jh_shared = Arc::new(jh);
let jh_cloned = Arc::clone(&jh_shared);
task::spawn(async move {
time::sleep(Duration::from_secs(5)).await;
jh_cloned.abort();
}).await;
let r = Arc::downgrade(&jh_shared);
let raw = r.into_raw();
unsafe { (*raw).await }; // <-- This here is invalid. Can I await wrapped JoinHandle in a different way?
}
So from my newbie code you can se that I want to be able to abort the running task in a separate task, and I need to have a handle on Future in the main thread too so I can await it of course, that is why I use Arc<T>.
Is there a way that could be done based on my code example or in a completely different way?
If it cannot be done the way I tried it I would like to know why?
Something
in task 0
in task 1
in task 2
in task 3
in task 4
signal to abort
tasks done
test in 50 millis done
Something
in task 0
in task 1
in task 2
in task 3
in task 4
signal to abort
JoinHandle aborted
test in 100 millis done
That is really nice advanced solution. I like that you wrapped data in JoinHandleAbort struct.
Combination with tokio::select! macro is powerful.
Thank you for this solution and to all others too.
Why spawning a new task if it is only to be able to abort it if it didn't end after a timeout ? It would be simpler to just select! between the long running future and sleep (or just wrap the future with tokio::time::timeout).
Still, if the task is required, it is simpler to wrap the JoinHandle in a tokio::time:: Timeout and await it like if it was running in same task but just abort and await the handle when it returns (whether timed out or not).
Yes I get it, I think. tokio::select! pseudo randomly chooses which Future to poll. So even when receiver gets signal to abort there is no guarantee when it will be polled.
Still I like your solution, now modified. tokio::time::timeout is simpler and more straight forward but in this case I need to be able to abort task (or not), in dynamic time, not statically set it when to abort up front.