Skip to content

Commit

Permalink
program parameter stopasgroup&killasgroup support
Browse files Browse the repository at this point in the history
  • Loading branch information
ochinchina committed Sep 24, 2018
1 parent 026fb4b commit c417e90
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 13 deletions.
10 changes: 8 additions & 2 deletions config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ autorestart=true
exitcodes=0,2
stopsignal=TERM
stopwaitsecs=10
#stopasgroup=not support
#killasgroup=not support
stopasgroup=true
killasgroup=true
user=user1
redirect_stderr=false
stdout_logfile=AUTO
Expand Down Expand Up @@ -106,6 +106,12 @@ serverurl=AUTO
buffer_size=10240
events=PROCESS_STATE
#result_handler=not support
[supervisorctl]
serverurl = unix:///tmp/supervisor.sock
username = chris
password = 123
#prompt = not support
`

type InitTemplateCommand struct {
Expand Down
34 changes: 26 additions & 8 deletions process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,16 +500,28 @@ func (p *Process) changeStateTo(procState ProcessState) {
p.state = procState
}

func (p *Process) Signal(sig os.Signal) error {
// send signal to the process
//
// Args:
// sig - the signal to the process
// sigChildren - true: send the signal to the process and its children proess
//
func (p *Process) Signal(sig os.Signal, sigChildren bool) error {
p.lock.Lock()
defer p.lock.Unlock()

return p.sendSignal(sig)
return p.sendSignal(sig, sigChildren)
}

func (p *Process) sendSignal(sig os.Signal) error {
// send signal to the process
//
// Args:
// sig - the signal to be sent
// sigChildren - true if the signal also need to be sent to children process
//
func (p *Process) sendSignal(sig os.Signal, sigChildren bool) error {
if p.cmd != nil && p.cmd.Process != nil {
err := signals.Kill(p.cmd.Process, sig)
err := signals.Kill(p.cmd.Process, sig, sigChildren)
return err
}
return fmt.Errorf("process is not started")
Expand Down Expand Up @@ -674,12 +686,18 @@ func (p *Process) setUser() error {

//send signal to process to stop it
func (p *Process) Stop(wait bool) {
p.lock.RLock()
p.lock.Lock()
p.stopByUser = true
p.lock.RUnlock()
p.lock.Unlock()
log.WithFields(log.Fields{"program": p.GetName()}).Info("stop the program")
sigs := strings.Fields(p.config.GetString("stopsignal", ""))
waitsecs := time.Duration(p.config.GetInt("stopwaitsecs", 10)) * time.Second
stopasgroup := p.config.GetBool("stopasgroup", false)
killasgroup := p.config.GetBool("killasgroup", stopasgroup)
if stopasgroup && !killasgroup {
log.WithFields(log.Fields{"program": p.GetName()}).Error("Cannot set stopasgroup=true and killasgroup=false")
}

go func() {
stopped := false
for i := 0; i < len(sigs) && !stopped; i++ {
Expand All @@ -689,7 +707,7 @@ func (p *Process) Stop(wait bool) {
continue
}
log.WithFields(log.Fields{"program": p.GetName(), "signal": sigs[i]}).Info("send stop signal to program")
p.Signal(sig)
p.Signal(sig, stopasgroup)
endTime := time.Now().Add(waitsecs)
//wait at most "stopwaitsecs" seconds for one signal
for endTime.After(time.Now()) {
Expand All @@ -703,7 +721,7 @@ func (p *Process) Stop(wait bool) {
}
if !stopped {
log.WithFields(log.Fields{"program": p.GetName()}).Info("force to kill the program")
p.Signal(syscall.SIGKILL)
p.Signal(syscall.SIGKILL, killasgroup)
}
}()
if wait {
Expand Down
15 changes: 13 additions & 2 deletions signals/signal.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,18 @@ func ToSignal(signalName string) (os.Signal, error) {

}

func Kill(process *os.Process, sig os.Signal) error {
// send signal to the process
//
// Args:
// process - the process which the signal should be sent to
// sig - the signal will be sent
// sigChildren - true if the signal needs to be sent to the children also
//
func Kill(process *os.Process, sig os.Signal, sigChildren bool) error {
localSig := sig.(syscall.Signal)
return syscall.Kill(-process.Pid, localSig)
pid := process.Pid
if sigChildren {
pid = -pid
}
return syscall.Kill(pid, localSig)
}
8 changes: 7 additions & 1 deletion signals/signal_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ func ToSignal(signalName string) (os.Signal, error) {

}

func Kill(process *os.Process, sig os.Signal) error {
//
// Args:
// process - the process
// sig - the signal
// sigChildren - ignore in windows system
//
func Kill(process *os.Process, sig os.Signal, sigChilren bool) error {
//Signal command can't kill children processes, call taskkill command to kill them
cmd := exec.Command("taskkill", "/F", "/T", "/PID", fmt.Sprintf("%d", process.Pid))
err := cmd.Start()
Expand Down

0 comments on commit c417e90

Please sign in to comment.