func (p *plugin) kill(wg *sync.WaitGroup) error { defer wg.Done() if p.IsProcessRunning() { defer p.connection.Close() conn.SendProcessKillMessage(p.connection) exited := make(chan bool, 1) go func() { for { if p.IsProcessRunning() { time.Sleep(100 * time.Millisecond) } else { exited <- true return } } }() select { case done := <-exited: if done { logger.Debug("Plugin [%s] with pid [%d] has exited", p.descriptor.Name, p.pluginCmd.Process.Pid) } case <-time.After(config.PluginConnectionTimeout()): logger.Warning("Plugin [%s] with pid [%d] did not exit after %.2f seconds. Forcefully killing it.", p.descriptor.Name, p.pluginCmd.Process.Pid, config.PluginConnectionTimeout().Seconds()) err := p.pluginCmd.Process.Kill() if err != nil { logger.Warning("Error while killing plugin %s : %s ", p.descriptor.Name, err.Error()) } return err } } return nil }
func (testRunner *TestRunner) Kill() error { if testRunner.IsProcessRunning() { defer testRunner.Connection.Close() conn.SendProcessKillMessage(testRunner.Connection) exited := make(chan bool, 1) go func() { for { if testRunner.IsProcessRunning() { time.Sleep(100 * time.Millisecond) } else { exited <- true return } } }() select { case done := <-exited: if done { return nil } case <-time.After(config.PluginKillTimeout()): logger.Warning("Killing runner with PID:%d forcefully", testRunner.Cmd.Process.Pid) return testRunner.killRunner() } } return nil }