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 scanner.Scan() {
 | 
			
		||||
			p.StdoutChannel <- scanner.Text()
 | 
			
		||||
		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 scanner.Scan() {
 | 
			
		||||
			p.StderrChannel <- scanner.Text()
 | 
			
		||||
		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 {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
func (p *Process) Wait() error {
 | 
			
		||||
	_, err := p.process.Process.Wait()
 | 
			
		||||
	close(p.exit)
 | 
			
		||||
	p.wg_exit.Wait()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user