process: Gracefully shutdown processes
Signed-off-by: Thomas Klaehn <thomas.klaehn@perinet.io>
This commit is contained in:
		@@ -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
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user