process: Gracefully shutdown processes
Signed-off-by: Thomas Klaehn <thomas.klaehn@perinet.io>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"os/exec"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -22,6 +23,9 @@ type Process struct {
|
||||
process *exec.Cmd
|
||||
stdout io.ReadCloser
|
||||
stderr io.ReadCloser
|
||||
|
||||
wg_exit *sync.WaitGroup
|
||||
exit chan struct{}
|
||||
}
|
||||
|
||||
func NewProcess(command string) *Process {
|
||||
@@ -38,40 +42,57 @@ func NewProcess(command string) *Process {
|
||||
}
|
||||
p.StdoutChannel = make(chan string)
|
||||
p.StderrChannel = make(chan string)
|
||||
p.wg_exit = &sync.WaitGroup{}
|
||||
p.exit = make(chan struct{})
|
||||
return p
|
||||
}
|
||||
|
||||
func (p Process) Start() error {
|
||||
func (p *Process) Start() error {
|
||||
err := p.process.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p Process) Observe() {
|
||||
p.wg_exit.Add(2)
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(p.stdout)
|
||||
for {
|
||||
select {
|
||||
case <-p.exit:
|
||||
p.wg_exit.Done()
|
||||
return
|
||||
default:
|
||||
for scanner.Scan() {
|
||||
p.StdoutChannel <- scanner.Text()
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(p.stderr)
|
||||
for {
|
||||
select {
|
||||
case <-p.exit:
|
||||
p.wg_exit.Done()
|
||||
return
|
||||
default:
|
||||
for scanner.Scan() {
|
||||
p.StderrChannel <- scanner.Text()
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p Process) Kill() {
|
||||
func (p Process) Stop() {
|
||||
p.process.Process.Kill()
|
||||
}
|
||||
|
||||
func (p Process) Wait() error {
|
||||
err := p.process.Wait()
|
||||
if err != nil {
|
||||
func (p *Process) Wait() error {
|
||||
_, err := p.process.Process.Wait()
|
||||
close(p.exit)
|
||||
p.wg_exit.Wait()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user