func (er *Runner) Run(ctx context.Context, pending chan<- Resignation) {
	pause := rand.Int63n(er.cfg.PreElectionPause.Nanoseconds())
	if err := clock.SleepSource(ctx, time.Duration(pause), er.cfg.TimeSource); err != nil {
		return  
	}
	glog.V(1).Infof("%s: start election-monitoring loop ", er.id)
	defer func() {
		glog.Infof("%s: shutdown election-monitoring loop", er.id)
		if err := er.election.Close(ctx); err != nil {
			glog.Warningf("%s: election.Close: %v", er.id, err)
		}
	}()
	for {
		if err := er.beMaster(ctx, pending); err != nil {
			glog.Errorf("%s: %v", er.id, err)
			break
		}
	}
}
Run performs a continuous election process. It runs continuously until the
context is canceled or an internal error is encountered.
package election
import (
	"context"
	"fmt"
	"math/rand"
	"time"
	"github.com/golang/glog"
	"github.com/google/trillian/util/clock"
	"github.com/google/trillian/util/election2"
)
const (
	MinPreElectionPause   = 10 * time.Millisecond
	MinMasterHoldInterval = 10 * time.Second
)
type RunnerConfig struct {
	PreElectionPause time.Duration
	MasterHoldInterval time.Duration
	MasterHoldJitter time.Duration
	TimeSource clock.TimeSource
}
func (cfg *RunnerConfig) ResignDelay() time.Duration {
	delay := cfg.MasterHoldInterval
	if cfg.MasterHoldJitter <= 0 {
		return delay
	}
	add := rand.Int63n(int64(cfg.MasterHoldJitter))
	return delay + time.Duration(add)
}
func fixupRunnerConfig(cfg *RunnerConfig) {
	if cfg.PreElectionPause < MinPreElectionPause {
		cfg.PreElectionPause = MinPreElectionPause
	}
	if cfg.MasterHoldInterval < MinMasterHoldInterval {
		cfg.MasterHoldInterval = MinMasterHoldInterval
	}
	if cfg.MasterHoldJitter < 0 {
		cfg.MasterHoldJitter = 0
	}
	if cfg.TimeSource == nil {
		cfg.TimeSource = clock.System
	}
}
type Runner struct {
	Cancel   context.CancelFunc
	id       string
	cfg      *RunnerConfig
	tracker  *MasterTracker
	election election2.Election
}
func NewRunner(id string, cfg *RunnerConfig, tracker *MasterTracker, cancel context.CancelFunc, el election2.Election) *Runner {
	fixupRunnerConfig(cfg)
	return &Runner{
		Cancel:   cancel,
		id:       id,
		cfg:      cfg,
		tracker:  tracker,
		election: el,
	}
}