Beispiel #1
0
// Stop the worker process
func (w *Worker) Stop(replyChan chan<- CommandReply) {
	//err := syscall.Kill(worker.Pid, syscall.SIGTERM)
	proc, err := os.FindProcess(w.Pid)
	if nil != err {
		w.Logger.Printf("worker.Stop(): Cannot find worker process %d: %s\n", w.Pid, err)
		//w.exitChannel <- w.dtoppedCommand(err, state, stalled)
		replyChan <- CommandReply{Reply: fmt.Sprintf("[%s] worker process %d already stopped", w.Taskname, w.Pid)}
		return
	}

	// attempt stopping the worker with a SIGTERM first
	err = proc.Signal(syscall.SIGTERM)
	if err != nil {
		if err.Error() == "os: process already finished" {
			w.Logger.Println("worker.Stop() SIGTERM sent to already dead process")
		} else {
			w.Logger.Printf("worker.Stop(): Error sending SIGTERM to worker process %d: %s\n", w.Pid, err)
		}
	}

	var msg string
	var cmd Command
	var state *os.ProcessState
	gracePeriod := time.Duration(w.GracePeriod) * time.Millisecond

	// wait until the process returns gracefully from the SIGTERM, or times out + is killed after a grace period
	select {
	case <-time.After(gracePeriod):
		w.Logger.Printf("Grace Period (%s) expired, killing worker process %d", gracePeriod, w.Pid)
		err = proc.Kill()
		msg = fmt.Sprintf("Worker process %d was still around after %s, killed.", w.Pid, gracePeriod)
		if nil != err {
			msg = fmt.Sprintf("worker.Stop(): Failed to kill process %d - %s", w.Pid, err.Error())
		}
		cmd = <-w.exitChannel // coming from waitOnProcess()
		cmd.Params["killed"] = true
	case cmd = <-w.exitChannel: // wait for the original waitpid() syscall in waitOnProcess() to return
		cmd.Params["killed"] = false
		err = nil
		msg = fmt.Sprintf("Worker process %d terminated gracefully", w.Pid)
		if state2, ok := cmd.Params["state"]; ok {
			state, ok = state2.(*os.ProcessState)
		}
		if err2, ok := cmd.Params["error"]; ok {
			if err, ok = err2.(error); ok {
				msg = fmt.Sprintf("Worker process %d terminated with error: (%T) %#v (%s)", w.Pid, err, err, state.String())
			}
		}
	}
	cmd.Params["stalled"] = w.HasStalled()
	//w.Logger.Println(msg)
	replyChan <- CommandReply{Reply: msg, Error: err}
	w.TaskFeedbackChannel <- cmd
}