func (runner *Runner) workerDone(info doneInfo) {
	workerInfo := runner.workers[info.id]
	if !workerInfo.stopping && info.err == nil {
		runner.params.Logger.Debugf("removing %q from known workers", info.id)
		runner.removeWorker(info.id, workerInfo.done)
		return
	}
	if info.err != nil {
		errStr := info.err.Error()
		if errWithStack, ok := info.err.(panicError); ok && errWithStack.Panicked() {
			// Panics should always have the full stacktrace in the error log.
			errStr = strings.Join(append([]string{errStr}, errWithStack.StackTrace()...), "\n")
		}
		if runner.params.IsFatal(info.err) {
			runner.params.Logger.Errorf("fatal %q: %s", info.id, errStr)
			if runner.finalError == nil || runner.params.MoreImportant(info.err, runner.finalError) {
				runner.finalError = info.err
			}
			runner.removeWorker(info.id, workerInfo.done)
			if !runner.isDying {
				runner.isDying = true
				runner.killAll()
			}
			return
		}
		runner.params.Logger.Errorf("exited %q: %s", info.id, errStr)
	}
	if workerInfo.start == nil {
		runner.params.Logger.Debugf("no restart, removing %q from known workers", info.id)

		// The worker has been deliberately stopped;
		// we can now remove it from the list of workers.
		runner.removeWorker(info.id, workerInfo.done)
		return
	}
	go runner.runWorker(workerInfo.restartDelay, info.id, workerInfo.start)
	workerInfo.restartDelay = runner.params.RestartDelay
}
// workerDone responds when a worker has finished or failed
// to start. It maintains the runner.finalError field and
// restarts the worker if necessary.
workerDone responds when a worker has finished or failed
to start. It maintains the runner.finalError field and
restarts the worker if necessary.
// workerDone responds when a worker has finished or failed // to start . It maintains the runner . finalError field and // restarts the worker if necessary .
func (runner *Runner) workerDone(info doneInfo) {
	workerInfo := runner.workers[info.id]
	if !workerInfo.stopping && info.err == nil {
		runner.params.Logger.Debugf("removing %q from known workers", info.id)
		runner.removeWorker(info.id, workerInfo.done)
		return
	}
	if info.err != nil {
		errStr := info.err.Error()
		if errWithStack, ok := info.err.(panicError); ok && errWithStack.Panicked() {
			errStr = strings.Join(append([]string{errStr}, errWithStack.StackTrace()...), "\n")
		}
		if runner.params.IsFatal(info.err) {
			runner.params.Logger.Errorf("fatal %q: %s", info.id, errStr)
			if runner.finalError == nil || runner.params.MoreImportant(info.err, runner.finalError) {
				runner.finalError = info.err
			}
			runner.removeWorker(info.id, workerInfo.done)
			if !runner.isDying {
				runner.isDying = true
				runner.killAll()
			}
			return
		}
		runner.params.Logger.Errorf("exited %q: %s", info.id, errStr)
	}
	if workerInfo.start == nil {
		runner.params.Logger.Debugf("no restart, removing %q from known workers", info.id)
		runner.removeWorker(info.id, workerInfo.done)
		return
	}
	go runner.runWorker(workerInfo.restartDelay, info.id, workerInfo.start)
	workerInfo.restartDelay = runner.params.RestartDelay
}
func ( runner * Runner ) workerDone ( info doneInfo ) { workerInfo := runner . workers [ info . id ] if ! workerInfo . stopping && info . err == nil { runner . params . Logger . Debugf ( " " , info . id ) runner . removeWorker ( info . id , workerInfo . done ) return } if info . err != nil { errStr := info . err . Error ( ) if errWithStack , ok := info . err . ( panicError ) ; ok && errWithStack . Panicked ( ) { errStr = strings . Join ( append ( [ ] string { errStr } , errWithStack . StackTrace ( ) ... ) , " \n " ) } if runner . params . IsFatal ( info . err ) { runner . params . Logger . Errorf ( " " , info . id , errStr ) if runner . finalError == nil || runner . params . MoreImportant ( info . err , runner . finalError ) { runner . finalError = info . err } runner . removeWorker ( info . id , workerInfo . done ) if ! runner . isDying { runner . isDying = true runner . killAll ( ) } return } runner . params . Logger . Errorf ( " " , info . id , errStr ) } if workerInfo . start == nil { runner . params . Logger . Debugf ( " " , info . id ) runner . removeWorker ( info . id , workerInfo . done ) return } go runner . runWorker ( workerInfo . restartDelay , info . id , workerInfo . start ) workerInfo . restartDelay = runner . params . RestartDelay }
workerDone responds when a worker has finished or failed
to start.
workerDone responds when a worker has finished or failed to start .
// Panics should always have the full stacktrace in the error log. // The worker has been deliberately stopped; // we can now remove it from the list of workers.