Created
February 4, 2025 14:23
-
-
Save evbruno/db33f3d8efde64f5c77c50b86a36da5d to your computer and use it in GitHub Desktop.
go - handling processes (GPT)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# OpenAI/GPT version of https://gist.github.com/evbruno/13ba9181b64eeb063079d8d1146125b4 | |
package main | |
import ( | |
"fmt" | |
"os" | |
"os/exec" | |
"os/signal" | |
"slices" | |
"syscall" | |
"time" | |
) | |
// ProcessJob represents a running process with its ID, command, and any encountered error. | |
type ProcessJob struct { | |
id int | |
err error | |
cmd string | |
} | |
func main() { | |
// Channels for handling signals and process status updates. | |
sigChan := make(chan os.Signal, 1) | |
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) | |
doneChan := make(chan ProcessJob, 1) | |
startChan := make(chan int) | |
processes := make([]int, 0) | |
fmt.Println("Starting process manager...") | |
// Launching multiple processes | |
go runProcess(doneChan, startChan, "bash", "-c", "sleep 10") | |
go runProcess(doneChan, startChan, "bash", "-c", "sleep 15") | |
// Main event loop for handling signals and process updates. | |
for { | |
select { | |
case pid := <-startChan: | |
// Store the process ID | |
processes = append(processes, pid) | |
fmt.Println("Processes started:", processes) | |
case job := <-doneChan: | |
// Process completion or failure handling | |
if job.err != nil { | |
fmt.Printf("Process %d failed: %v\n", job.id, job.err) | |
} else { | |
fmt.Printf("Process %d completed: %s\n", job.id, job.cmd) | |
} | |
// Remove completed process from list | |
if idx := slices.Index(processes, job.id); idx != -1 { | |
processes = slices.Delete(processes, idx, idx+1) | |
} | |
fmt.Println("Active processes:", processes) | |
case <-sigChan: | |
// Handle termination signal (CTRL+C) | |
fmt.Println("\nCTRL+C received! Terminating all processes...") | |
terminateProcesses(processes) | |
} | |
} | |
} | |
// runProcess starts a command as a child process and reports its status. | |
func runProcess(done chan ProcessJob, start chan int, name string, args ...string) { | |
cmdStr := fmt.Sprintf("%s %s", name, args) | |
cmd := exec.Command(name, args...) | |
fmt.Println("Starting process:", cmdStr) | |
// Start the process | |
if err := cmd.Start(); err != nil { | |
fmt.Println("Error starting process:", err) | |
done <- ProcessJob{0, err, cmdStr} | |
return | |
} | |
// Notify that the process has started | |
start <- cmd.Process.Pid | |
fmt.Println("Process running (PID):", cmd.Process.Pid) | |
// Wait for process completion | |
err := cmd.Wait() | |
// Report process status | |
done <- ProcessJob{cmd.Process.Pid, err, cmdStr} | |
if err != nil { | |
fmt.Println("Process exited with error:", err) | |
} else { | |
fmt.Println("Process completed successfully:", cmdStr) | |
} | |
} | |
// terminateProcesses stops all running processes. | |
func terminateProcesses(pids []int) { | |
for _, pid := range pids { | |
fmt.Printf("Stopping process (PID: %d)\n", pid) | |
_ = syscall.Kill(-pid, syscall.SIGKILL) // Kill entire process group | |
} | |
time.Sleep(1 * time.Second) // Allow time for cleanup | |
fmt.Println("All processes terminated.") | |
os.Exit(1) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment