From be0b0eff2421ecf250e68201b2dbe01637631842 Mon Sep 17 00:00:00 2001 From: Emre Karabay Date: Fri, 27 Dec 2024 22:11:49 -0500 Subject: [PATCH] Improved process termination logic in process_unix.go --- utils/process_unix.go | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/utils/process_unix.go b/utils/process_unix.go index bf9a050..7c649a8 100644 --- a/utils/process_unix.go +++ b/utils/process_unix.go @@ -3,7 +3,10 @@ package utils +// Dummy test thing + import ( + "errors" "fmt" "os" "syscall" @@ -22,23 +25,45 @@ func IsProcessRunning(pid int) bool { return err == nil } -// StopProcess stops a process by its PID on Unix-based systems. func StopProcess(pid int) error { - process, err := os.FindProcess(pid) - if err != nil { + // Check if the process exists + if _, err := os.FindProcess(pid); err != nil { return fmt.Errorf("could not find process: %w", err) } - // Send SIGTERM (soft termination) - err = process.Signal(syscall.SIGTERM) + // Send SIGTERM to the process group + err := syscall.Kill(-pid, syscall.SIGTERM) if err != nil { - return fmt.Errorf("could not terminate process: %w", err) + return fmt.Errorf("could not send SIGTERM to process: %w", err) } + fmt.Printf("SIGTERM sent to process group %d\n", pid) - // termination might take some time and it will effect the next steps during update, sleep 5 seconds just in case - time.Sleep(5 * time.Second) + // Wait for graceful termination + timeout := time.After(10 * time.Second) + ticker := time.NewTicker(500 * time.Millisecond) + defer ticker.Stop() - return nil + for { + select { + case <-timeout: + // Escalate to SIGKILL if process does not terminate + err = syscall.Kill(-pid, syscall.SIGKILL) + if err != nil { + return fmt.Errorf("could not kill process: %w", err) + } + fmt.Printf("SIGKILL sent to process group %d\n", pid) + time.Sleep(1 * time.Second) + if IsProcessRunning(pid) { + return errors.New("process did not terminate even after SIGKILL") + } + return fmt.Errorf("process did not terminate gracefully; sent SIGKILL") + case <-ticker.C: + if !IsProcessRunning(pid) { + fmt.Printf("Process group %d terminated successfully\n", pid) + return nil + } + } + } } func SetFileDescriptorLimit(limit uint64) error {