85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
// a vibe coded el cheapo: https://claude.ai/chat/328ca558-1019-49b9-9f08-e85cfcea2ceb
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
func runProcess(ctx context.Context, wg *sync.WaitGroup, name, command string) {
|
|
defer wg.Done()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
fmt.Printf("[%s] Stopping\n", name)
|
|
return
|
|
default:
|
|
fmt.Printf("[%s] Starting: %s\n", name, command)
|
|
|
|
// Create command with context for cancellation
|
|
cmd := exec.CommandContext(ctx, "sh", "-c", command)
|
|
|
|
// Setup stdout pipe
|
|
stdout, err := cmd.StdoutPipe()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "[%s] Error creating stdout pipe: %v\n", name, err)
|
|
return
|
|
}
|
|
|
|
// Setup stderr pipe
|
|
stderr, err := cmd.StderrPipe()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "[%s] Error creating stderr pipe: %v\n", name, err)
|
|
return
|
|
}
|
|
|
|
// Start the command
|
|
if err := cmd.Start(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "[%s] Error starting command: %v\n", name, err)
|
|
time.Sleep(time.Second)
|
|
continue
|
|
}
|
|
|
|
// Copy output in separate goroutines
|
|
var ioWg sync.WaitGroup
|
|
ioWg.Add(2)
|
|
|
|
go func() {
|
|
defer ioWg.Done()
|
|
io.Copy(os.Stdout, stdout)
|
|
}()
|
|
|
|
go func() {
|
|
defer ioWg.Done()
|
|
io.Copy(os.Stderr, stderr)
|
|
}()
|
|
|
|
// Wait for command to finish
|
|
err = cmd.Wait()
|
|
ioWg.Wait() // Ensure all output is copied
|
|
|
|
// Check if we should restart
|
|
select {
|
|
case <-ctx.Done():
|
|
fmt.Printf("[%s] Stopped\n", name)
|
|
return
|
|
default:
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "[%s] Process exited with error: %v\n", name, err)
|
|
} else {
|
|
fmt.Printf("[%s] Process exited normally\n", name)
|
|
}
|
|
fmt.Printf("[%s] Restarting in 1 second...\n", name)
|
|
time.Sleep(time.Second)
|
|
}
|
|
}
|
|
}
|
|
}
|