wip: initial test

This commit is contained in:
2023-11-22 13:23:39 +11:00
parent ce9df6364f
commit 3cf595f08e
7 changed files with 130 additions and 30 deletions

View File

@@ -1,31 +1,60 @@
use tokio::task::JoinSet;
use tokio::process::Command;
use tokio_util::sync::CancellationToken;
use tokio::select;
use tokio::io::Result as tokio_result;
use tokio::time::sleep;
use std::time::Duration;
use std::process::ExitStatus;
use std::error;
use nix::sys::signal::{kill, Signal};
use nix::errno::Errno;
use nix::unistd::Pid;
pub fn start_process(ts: &mut JoinSet<Result<(), Box<dyn error::Error + Send + Sync>>>) {
pub fn start_process(ts: &mut JoinSet<Result<(), Box<dyn error::Error + Send + Sync>>>, cancel: CancellationToken) {
for _j in 0..5 {
let cancel = cancel.clone();
ts.spawn(async move {
for _i in 0..5 {
'autorestart: loop {
let mut child = Command::new("sleep").arg("1")
.spawn()
.expect("failed to spawn");
match child.wait().await {
Ok(status) => {
println!("starter: sleep exited: {}", status);
},
Err(e) => {
if let Some(eos) = e.raw_os_error() {
if eos != nix::Error::ECHILD as i32 {
return Err(e.into());
select! {
_ = cancel.cancelled() => {
if let Some(id) = child.id() {
match kill(Pid::from_raw(id as i32), Some(Signal::SIGTERM)) {
Ok(_) => {
select! {
_ = sleep(Duration::from_secs(5)) => {
child.kill().await.expect("failed to kill process");
},
result = child.wait() => {
if let Err(e) = result_match(result) {
return Err(e);
}
break 'autorestart;
}
}
},
Err(e) => {
if e != Errno::ESRCH {
return Err(e.into());
} else {
break 'autorestart;
}
}
}
} else {
return Err(e.into());
}
},
result = child.wait() => {
if let Err(e) = result_match(result) {
return Err(e);
}
},
}
// let status = child.wait().await?;
// println!("starter: sleep exited: {}", status);
}
println!("starter: task completed");
Ok(())
@@ -33,4 +62,21 @@ pub fn start_process(ts: &mut JoinSet<Result<(), Box<dyn error::Error + Send + S
}
println!("starter: spawning completed");
}
fn result_match(result: tokio_result<ExitStatus>) -> Result<(), Box<dyn error::Error + Send + Sync>> {
if let Err(e) = result {
if let Some(eos) = e.raw_os_error() {
if eos != nix::Error::ECHILD as i32 {
return Err(e.into());
}
} else {
return Err(e.into());
}
}
//TODO: remove me! this is for debug + tracing purpose
println!("starter: sleep exited");
Ok(())
}