Skip to content

Commit

Permalink
Improve task termination
Browse files Browse the repository at this point in the history
* First, terminate the task with `schtasks.exe /end ...`.
* Then, try to kill the actual test run. In case this fails because the
  PID file is empty or doesn't exist, the test hasn't started yet, so we
  are good.
  • Loading branch information
jherbel committed Nov 9, 2023
1 parent 03f64c3 commit be58ad1
Showing 1 changed file with 8 additions and 18 deletions.
26 changes: 8 additions & 18 deletions v2/robotmk/src/bin/scheduler/sessions/schtasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use log::{debug, error};
use std::fs::{read_to_string, write};
use std::process::Command;
use std::str::FromStr;
use std::thread::sleep;
use std::time::Duration;
use sysinfo::Pid;

Expand Down Expand Up @@ -186,14 +185,18 @@ fn query_if_task_is_running(task_name: &str) -> Result<bool> {
}

fn kill_and_delete_task(task_name: &str, path_pid: &Utf8Path) {
// schtasks.exe /end ... terminates the batch script, but child processes will survive ...
error!("Killing and deleting task {task_name}");
let _ = kill_task(path_pid).map_err(log_and_return_error);
let _ = kill_task(task_name, path_pid).map_err(log_and_return_error);
delete_task(task_name);
}

fn kill_task(path_pid: &Utf8Path) -> Result<()> {
let raw_pid = read_pid(path_pid)?;
fn kill_task(task_name: &str, path_pid: &Utf8Path) -> Result<()> {
// schtasks.exe /end ... terminates the batch script, but child processes will survive. Therefore,
// we additionally try to kill the actual test run. In case the PID file is empty, no tests have
// started yet, so we are ok.
let _ = run_schtasks(["/end", "/tn", task_name]).map_err(log_and_return_error);
let raw_pid = read_until_first_whitespace(path_pid)
.context(format!("Failed to read PID from {path_pid}"))?;
kill_process_tree(
&Pid::from_str(&raw_pid).context(format!("Failed to parse {} as PID", raw_pid))?,
);
Expand All @@ -216,19 +219,6 @@ fn read_until_first_whitespace(path: &Utf8Path) -> Result<String> {
.to_string())
}

fn read_pid(path: &Utf8Path) -> Result<String> {
match read_until_first_whitespace(path) {
Ok(pid) => return Ok(pid),
Err(err) => {
log_and_return_error(err.context(format!(
"Failed to read PID from {path}, will sleep 1s and try one more time"
)));
}
};
sleep(Duration::from_secs(1));
read_until_first_whitespace(path).context(format!("Failed to read PID from {path}"))
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit be58ad1

Please sign in to comment.