ex: Add example for timed out process (#38)
This commit is contained in:
parent
9f57bbfeb7
commit
e41847a378
|
@ -43,3 +43,6 @@ features = [
|
|||
"Win32_System_Threading",
|
||||
"Win32_System_WindowsProgramming"
|
||||
]
|
||||
|
||||
[dev-dependencies]
|
||||
async-io = "1.8"
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
//! An example of running a `Command` with a timeout.
|
||||
|
||||
use async_io::Timer;
|
||||
use async_process::{Command, Stdio};
|
||||
use futures_lite::{future, prelude::*};
|
||||
use std::io;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
async_io::block_on(async {
|
||||
// Spawn a a command of your choice.
|
||||
let mut child = Command::new("sleep")
|
||||
.arg("3")
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()?;
|
||||
|
||||
// Run a future to drain the stdout of the child.
|
||||
// We can't use output() here because it would be cancelled along with the child when the timeout
|
||||
// expires.
|
||||
let mut stdout = String::new();
|
||||
let drain_stdout = {
|
||||
let buffer = &mut stdout;
|
||||
let mut stdout = child.stdout.take().unwrap();
|
||||
|
||||
async move {
|
||||
stdout.read_to_string(buffer).await?;
|
||||
|
||||
// Wait for the child to exit or the timeout.
|
||||
future::pending().await
|
||||
}
|
||||
};
|
||||
|
||||
// Run a future to drain the stderr of the child.
|
||||
let mut stderr = String::new();
|
||||
let drain_stderr = {
|
||||
let buffer = &mut stderr;
|
||||
let mut stderr = child.stderr.take().unwrap();
|
||||
|
||||
async move {
|
||||
stderr.read_to_string(buffer).await?;
|
||||
|
||||
// Wait for the child to exit or the timeout.
|
||||
future::pending().await
|
||||
}
|
||||
};
|
||||
|
||||
// Run a future that waits for the child to exit.
|
||||
let wait = async move {
|
||||
child.status().await?;
|
||||
|
||||
// Child exited.
|
||||
io::Result::Ok(false)
|
||||
};
|
||||
|
||||
// Run a future that times out after 5 seconds.
|
||||
let timeout_s = 1;
|
||||
let timeout = async move {
|
||||
Timer::after(std::time::Duration::from_secs(timeout_s)).await;
|
||||
|
||||
// Timed out.
|
||||
Ok(true)
|
||||
};
|
||||
|
||||
// Run the futures concurrently.
|
||||
// Note: For larger scale programs than this you should probably spawn each individual future on
|
||||
// a separate task in an executor.
|
||||
let timed_out = drain_stdout.or(drain_stderr).or(wait).or(timeout).await?;
|
||||
|
||||
if timed_out {
|
||||
println!("The child timed out.");
|
||||
} else {
|
||||
println!("The child exited.");
|
||||
}
|
||||
|
||||
println!("Stdout:\n{}", stdout);
|
||||
println!("Stderr:\n{}", stderr);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue