process: Gracefully shutdown processes

Signed-off-by: Thomas Klaehn <thomas.klaehn@perinet.io>
This commit is contained in:
Thomas Klaehn
2025-09-10 08:46:56 +02:00
parent 35bbcd7a6d
commit 4c260dece6

View File

@@ -5,6 +5,7 @@ import (
"io" "io"
"log" "log"
"os/exec" "os/exec"
"sync"
) )
var ( var (
@@ -22,6 +23,9 @@ type Process struct {
process *exec.Cmd process *exec.Cmd
stdout io.ReadCloser stdout io.ReadCloser
stderr io.ReadCloser stderr io.ReadCloser
wg_exit *sync.WaitGroup
exit chan struct{}
} }
func NewProcess(command string) *Process { func NewProcess(command string) *Process {
@@ -38,40 +42,57 @@ func NewProcess(command string) *Process {
} }
p.StdoutChannel = make(chan string) p.StdoutChannel = make(chan string)
p.StderrChannel = make(chan string) p.StderrChannel = make(chan string)
p.wg_exit = &sync.WaitGroup{}
p.exit = make(chan struct{})
return p return p
} }
func (p Process) Start() error { func (p *Process) Start() error {
err := p.process.Start() err := p.process.Start()
if err != nil { if err != nil {
return err return err
} }
return nil
}
func (p Process) Observe() { p.wg_exit.Add(2)
go func() { go func() {
scanner := bufio.NewScanner(p.stdout) scanner := bufio.NewScanner(p.stdout)
for {
select {
case <-p.exit:
p.wg_exit.Done()
return
default:
for scanner.Scan() { for scanner.Scan() {
p.StdoutChannel <- scanner.Text() p.StdoutChannel <- scanner.Text()
} }
}
}
}() }()
go func() { go func() {
scanner := bufio.NewScanner(p.stderr) scanner := bufio.NewScanner(p.stderr)
for {
select {
case <-p.exit:
p.wg_exit.Done()
return
default:
for scanner.Scan() { for scanner.Scan() {
p.StderrChannel <- scanner.Text() p.StderrChannel <- scanner.Text()
} }
}
}
}() }()
return nil
} }
func (p Process) Kill() { func (p Process) Stop() {
p.process.Process.Kill() p.process.Process.Kill()
} }
func (p Process) Wait() error { func (p *Process) Wait() error {
err := p.process.Wait() _, err := p.process.Process.Wait()
if err != nil { close(p.exit)
p.wg_exit.Wait()
return err return err
} }
return nil
}