Files
diachron/monitor/devrunner.go
2026-01-01 12:26:54 -06:00

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)
}
}
}
}