func (runner *Runner) runWorker(delay time.Duration, id string, start func() (Worker, error)) {
	if delay > 0 {
		runner.params.Logger.Infof("restarting %q in %v", id, delay)
		// TODO(rog) provide a way of interrupting this
		// so that it can be stopped when a worker is removed.
		select {
		case <-runner.tomb.Dying():
			runner.donec <- doneInfo{id, nil}
			return
		case <-runner.params.Clock.After(delay):
		}
	}
	runner.params.Logger.Infof("start %q", id)

	// Defensively ensure that we get reasonable behaviour
	// if something calls Goexit inside the worker (this can
	// happen if something calls check.Assert) - if we don't
	// do this, then this will usually turn into a hard-to-find
	// deadlock when the runner is stopped but the runWorker
	// goroutine will never signal that it's finished.
	normal := false
	defer func() {
		if normal {
			return
		}
		// Since normal isn't true, it means that something
		// inside start must have called panic or runtime.Goexit.
		// If it's a panic, we let it panic; if it's called Goexit,
		// we'll just return an error, enabling this functionality
		// to be tested.
		if err := recover(); err != nil {
			panic(err)
		}
		runner.params.Logger.Infof("%q called runtime.Goexit unexpectedly", id)
		runner.donec <- doneInfo{id, errors.Errorf("runtime.Goexit called in running worker - probably inappropriate Assert")}
	}()
	worker, err := start()
	normal = true

	if err == nil {
		runner.startedc <- startInfo{id, worker}
		err = worker.Wait()
	}
	runner.params.Logger.Infof("stopped %q, err: %v", id, err)
	runner.donec <- doneInfo{id, err}
}
// runWorker starts the given worker after waiting for the given delay.
runWorker starts the given worker after waiting for the given delay.
// runWorker starts the given worker after waiting for the given delay .
func (runner *Runner) runWorker(delay time.Duration, id string, start func() (Worker, error)) {
	if delay > 0 {
		runner.params.Logger.Infof("restarting %q in %v", id, delay)
		select {
		case <-runner.tomb.Dying():
			runner.donec <- doneInfo{id, nil}
			return
		case <-runner.params.Clock.After(delay):
		}
	}
	runner.params.Logger.Infof("start %q", id)
	normal := false
	defer func() {
		if normal {
			return
		}
		if err := recover(); err != nil {
			panic(err)
		}
		runner.params.Logger.Infof("%q called runtime.Goexit unexpectedly", id)
		runner.donec <- doneInfo{id, errors.Errorf("runtime.Goexit called in running worker - probably inappropriate Assert")}
	}()
	worker, err := start()
	normal = true
	if err == nil {
		runner.startedc <- startInfo{id, worker}
		err = worker.Wait()
	}
	runner.params.Logger.Infof("stopped %q, err: %v", id, err)
	runner.donec <- doneInfo{id, err}
}
func ( runner * Runner ) runWorker ( delay time . Duration , id string , start func ( ) ( Worker , error ) ) { if delay > 0 { runner . params . Logger . Infof ( " " , id , delay ) select { case <- runner . tomb . Dying ( ) : runner . donec <- doneInfo { id , nil } return case <- runner . params . Clock . After ( delay ) : } } runner . params . Logger . Infof ( " " , id ) normal := false defer func ( ) { if normal { return } if err := recover ( ) ; err != nil { panic ( err ) } runner . params . Logger . Infof ( " " , id ) runner . donec <- doneInfo { id , errors . Errorf ( " " ) } } ( ) worker , err := start ( ) normal = true if err == nil { runner . startedc <- startInfo { id , worker } err = worker . Wait ( ) } runner . params . Logger . Infof ( " " , id , err ) runner . donec <- doneInfo { id , err } }
runWorker starts the given worker after waiting for the given delay.
runWorker starts the given worker after waiting for the given delay .
// TODO(rog) provide a way of interrupting this // so that it can be stopped when a worker is removed. // Defensively ensure that we get reasonable behaviour // if something calls Goexit inside the worker (this can // happen if something calls check.Assert) - if we don't // do this, then this will usually turn into a hard-to-find // deadlock when the runner is stopped but the runWorker // goroutine will never signal that it's finished. // Since normal isn't true, it means that something // inside start must have called panic or runtime.Goexit. // If it's a panic, we let it panic; if it's called Goexit, // we'll just return an error, enabling this functionality // to be tested.