From be58ad1bc5acab13d7e787d9da6bec8f8e9dfb50 Mon Sep 17 00:00:00 2001
From: Joerg Herbel <joerg.herbel@checkmk.com>
Date: Thu, 9 Nov 2023 13:32:46 +0100
Subject: [PATCH] Improve task termination

* 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.
---
 .../src/bin/scheduler/sessions/schtasks.rs    | 26 ++++++-------------
 1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/v2/robotmk/src/bin/scheduler/sessions/schtasks.rs b/v2/robotmk/src/bin/scheduler/sessions/schtasks.rs
index 637a47fc..7262d6a5 100644
--- a/v2/robotmk/src/bin/scheduler/sessions/schtasks.rs
+++ b/v2/robotmk/src/bin/scheduler/sessions/schtasks.rs
@@ -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;
 
@@ -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))?,
     );
@@ -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::*;