Now can reliably run multiple processes and kill them externall at will.

master
Zed A. Shaw 2 days ago
parent fe091250bd
commit 8a0f8ece61
  1. 8
      .ozai.json
  2. 8
      config/settings.go
  3. 73
      main.go
  4. 12
      tools/cmd/tester/main.go

@ -1,14 +1,14 @@
{ {
"Processes": { "Processes": {
"tester1": { "tester1": {
"Name": "tester", "Name": "tester1",
"Command": "tester", "Command": "tester",
"Args": ["-count", "10", "-id", "1"] "Args": ["-count", "100", "-id", "1"]
}, },
"tester2": { "tester2": {
"Name": "tester", "Name": "tester2",
"Command": "tester", "Command": "tester",
"Args": ["-count", "5", "-id", "2"] "Args": ["-count", "500", "-id", "2"]
} }
} }
} }

@ -5,16 +5,20 @@ import (
"log" "log"
"os" "os"
"io" "io"
"os/exec"
"encoding/json" "encoding/json"
) )
type command struct { type Process struct {
Command string Command string
Args []string Args []string
Name string
Ready chan string
ExecCmd *exec.Cmd
} }
type config struct { type config struct {
Processes map[string]command Processes map[string]Process
ConfigPath string ConfigPath string
} }

@ -6,6 +6,7 @@ import (
"log" "log"
"io" "io"
"time" "time"
"math/rand"
"os" "os"
"errors" "errors"
"sync" "sync"
@ -16,12 +17,39 @@ func LaunchLogger(in io.Reader, out io.Writer, err error) {
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
go func() { go func() {
if _, err := io.Copy(out, in); err != nil { if _, err := io.Copy(out, in)
log.Fatal(err)
} err != nil { log.Printf("LOGGER: %v", err) }
}() }()
} }
func LaunchProcess(proc *config.Process, wg sync.WaitGroup) {
defer wg.Done()
for {
proc.ExecCmd = exec.Command(proc.Command, proc.Args...)
if errors.Is(proc.ExecCmd.Err, exec.ErrDot) {
proc.ExecCmd.Err = nil
}
fmt.Println("STARTING", proc.Name)
stderr, err := proc.ExecCmd.StderrPipe();
LaunchLogger(stderr, os.Stdout, err)
stdout, err := proc.ExecCmd.StdoutPipe();
LaunchLogger(stdout, os.Stdout, err)
proc.ExecCmd.Start()
fmt.Println("WAITING for", proc.Name)
fmt.Println("SENDING READY on channel")
proc.Ready<- "ready"
proc.ExecCmd.Wait()
fmt.Println("PROCESS", proc.Name, "EXITED")
}
}
func main() { func main() {
config.Load() config.Load()
@ -33,34 +61,21 @@ func main() {
fmt.Println("PROCESS:", name) fmt.Println("PROCESS:", name)
wg.Add(1) wg.Add(1)
go func() { proc.Ready = make(chan string)
defer wg.Done() go LaunchProcess(&proc, wg)
go func() {
for { for {
fmt.Println("STARTING", name) fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!! killer runs")
cmd := exec.Command(proc.Command, proc.Args...) is_ready := <-proc.Ready
if errors.Is(cmd.Err, exec.ErrDot) {
cmd.Err = nil fmt.Println("is_ready returned", is_ready)
} sleep_for := rand.Int() % 10 + 1
time.Sleep(time.Duration(sleep_for) * time.Second)
stderr, err := cmd.StderrPipe(); fmt.Println("!!!!!!!!!!!!!!!!!!! TIME TO DIE!!!!!")
LaunchLogger(stderr, os.Stdout, err)
err := proc.ExecCmd.Process.Kill()
stdout, err := cmd.StdoutPipe(); if err != nil { log.Printf("killer says: %v", err) }
LaunchLogger(stdout, os.Stdout, err)
cmd.Run()
fmt.Println("WAITING for", name)
go func() {
fmt.Println("killer runs")
time.Sleep(4 * time.Second)
fmt.Println("!!!!!!!!!!!!!!!!!!! TIME TO DIE!!!!!")
cmd.Process.Signal(os.Interrupt)
}()
cmd.Wait()
fmt.Println("PROC", name, "EXITED SEND QUIT")
} }
}() }()
} }

@ -7,11 +7,12 @@ import (
"sync" "sync"
) )
func Worker(name string, done chan<- int, stop <-chan int) { func Worker(name string, count int, done chan<- int, stop <-chan int) {
for i := 0; i < 10; i++ { for i := 0; i < count; i++ {
select { select {
case <-stop: case <-stop:
fmt.Println("Worker stopped:", name) fmt.Println("Worker stopped:", name)
done<- 1
return return
default: default:
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
@ -26,15 +27,14 @@ func Supervisor(id int, count int) {
stop := make(chan int) stop := make(chan int)
var wg sync.WaitGroup var wg sync.WaitGroup
for i := 0; i < count; i++ { for i := 0; i < 5; i++ {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
for { for {
workerDone := make(chan int) workerDone := make(chan int)
go Worker(fmt.Sprintf("%d:%d", id, i), workerDone, stop) go Worker(fmt.Sprintf("%d:%d", id, i), count, workerDone, stop)
select { select {
case <-workerDone: case <-workerDone:
@ -48,11 +48,13 @@ func Supervisor(id int, count int) {
}() }()
} }
/*
go func() { go func() {
// test shutdown // test shutdown
time.Sleep(10000 * time.Millisecond) time.Sleep(10000 * time.Millisecond)
close(stop) close(stop)
}() }()
*/
wg.Wait() wg.Wait()
} }

Loading…
Cancel
Save