I have a CLI-based application that performs long computations in the background. While it performs the background computation, I want to display progress in the console, and once the background task is complete I want to use the return code to display the correct message ex: update success/ failed, etc.
Here's an example of how the application will look like:
Updating the driver
................................
Update completed successfully
To execute the task async fn update_device() -> u8{ }
in the background I can use async function and call tokio::task::spawn() on it, and call .await on the JoinHandle. But I want to know how can I show the progress, while the updates are going.
I checked the JoinHandle
in tokio has a function is_finished()
, but I don't know how to call it or use it for this purpose.
I want to display progress in the console, and once the background task is complete I want to use the return code to display the correct message ex: update success/ failed, etc.
When I try to call is_finished
before await
ing like this:
async fn update_device() -> u8{
tokio::time::sleep(Duration::from_sec(5000)).await;
}
fn test(){
println!("Updating the driver");
let handle = tokio::task::spawn(update_device());
loop{
if handle.is_finished() == true{
break;
}
print!(".")
}
println!("Driver Update succesfully");
}
fn main() {
test()
}
I get the error
there's no reactor running, must be called from the context of a Tokio 1.x runtime
is_finished
has to be called from within a running runtime, otherwise there is nothing that could advance the Future
and thus it would always return the same false
, the easiest to adapt your code is to use the attribute #[tokio::main]
:
use std::io::Write;
use core::time::Duration;
#[tokio::main]
async fn test() {
let h = tokio::task::spawn(update_device());
while !h.is_finished() {
tokio::time::sleep(Duration::from_millis(250)).await;
print!(".");
std::io::stdout().flush().unwrap();
}
println!();
if h.await.unwrap() == 0 {
println!("Update completed successfully");
} else {
println!("Update failed");
}
}
async fn update_device() -> u8 {
println!("Updating the driver");
tokio::time::sleep(Duration::from_secs(2)).await;
0
}
fn main() {
test()
}