Reputation: 188
I've a program that tracks file change and should restart a specified process on file change.
I use cmd.Process.Kill()
to kill previous process but it keeps alive after Kill()
called.
Some piece of code related to process start from project:
// ShellPlugin allows to run shell commands in task runner
type ShellPlugin struct {
scope *scope.Scope
params Params
log logging.Logger
done chan bool
}
// Call calls a plugin
func (p *ShellPlugin) Call(tx *job.RunContext, r plugins.JobRunner) (err error) {
defer close(p.done)
// process: /bin/sh -c ping google.com
cmd, err := p.params.createProcess(p.scope)
if err != nil {
return fmt.Errorf("failed to create process to execute command '%s': %s", p.params.Command, err)
}
p.log.Debug("command: '%s'", p.params.Command)
p.log.Debug(`starting process "%s"...`, strings.Join(cmd.Args, " "))
if err = cmd.Start(); err != nil {
return fmt.Errorf(`failed to execute command "%s": %s`, strings.Join(cmd.Args, " "), err)
}
go func() {
select {
case <- p.done:
p.log.Debug("received stop signal")
if err := cmd.Process.Kill(); err != nil {
p.log.Warn("kill: %s", err.Error())
}
p.log.Debug("Killed")
}
}()
if err := cmd.Wait(); err != nil {
return formatExitError(err)
}
p.log.Debug("done")
return nil
}
// Cancel called when task should be canceled
func (p *ShellPlugin) Cancel(ctx *job.RunContext) error {
p.done <- true
return nil
}
Call()
starts job and Cancel()
cancel it.
Both called in separate goroutine.
Full source code is here
Upvotes: 2
Views: 259
Reputation: 188
The issue was that the main process sh
was killed but child process sleep
was still alive.
The solution was to assign process group to the main process and kill a whole process group.
// assign process group
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
// Kill pg
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
Solution was found here
Upvotes: 2