はじめに
Rustでタイムアウト時間を設定して外部コマンドを実行する際にそこそこ苦労したので備忘録として残しておきます。
環境
- OS: Windows 10
- rust: 1.70.0
方法
1. wait-timeout
クレート追加
cargo add wait-timeout
Cargo.toml
[dependencies]
wait-timeout = "0.2.0"
2. タイムアウト時間を設定して実行
タイムアウト時間を10秒に設定してsample.exe
を実行する場合は以下のようになります。
タイムアウトの発生,または実行時エラーが発生した場合はpanicし,成功した場合は出力を標準出力に出力しています。
main.rs
use std::{
io::Read,
process::{Command, Stdio},
time::Duration,
};
use wait_timeout::ChildExt;
/// タイムアウト時間
static TIME_LIMIT: u64 = 10;
fn main() {
let duration = Duration::from_secs(TIME_LIMIT);
let mut child = Command::new("./sample.exe")
.stdout(Stdio::piped())
.spawn()
.unwrap();
// タイムアウト処理
let status = match child.wait_timeout(duration).unwrap() {
Some(status) => status,
None => {
child.kill().unwrap();
child.wait().unwrap();
panic!("タイムアウトエラー");
}
};
if !status.success() {
panic!("実行時エラー");
}
// 標準出力を取得
let mut stdout = String::new();
child.stdout.unwrap().read_to_string(&mut stdout).unwrap();
println!("{}", stdout);
}
実際に実行に10秒以上時間がかかるsample.exe
を実行させてみるとタイムアウトエラーを吐いてくれました。
> cargo run -q
thread 'main' panicked at 'タイムアウトエラー', src\main.rs:26:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace