github.com/mongey/nomad@v0.5.2/command/agent/consul/check.go (about)

     1  package consul
     2  
     3  import (
     4  	"log"
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/hashicorp/consul/lib"
     9  	cstructs "github.com/hashicorp/nomad/client/driver/structs"
    10  )
    11  
    12  // CheckRunner runs a given check in a specific interval and update a
    13  // corresponding Consul TTL check
    14  type CheckRunner struct {
    15  	check    Check
    16  	runCheck func(Check)
    17  	logger   *log.Logger
    18  	stop     bool
    19  	stopCh   chan struct{}
    20  	stopLock sync.Mutex
    21  
    22  	started     bool
    23  	startedLock sync.Mutex
    24  }
    25  
    26  // NewCheckRunner configures and returns a CheckRunner
    27  func NewCheckRunner(check Check, runCheck func(Check), logger *log.Logger) *CheckRunner {
    28  	cr := CheckRunner{
    29  		check:    check,
    30  		runCheck: runCheck,
    31  		logger:   logger,
    32  		stopCh:   make(chan struct{}),
    33  	}
    34  	return &cr
    35  }
    36  
    37  // Start is used to start the check. The check runs until stop is called
    38  func (r *CheckRunner) Start() {
    39  	r.startedLock.Lock()
    40  	defer r.startedLock.Unlock()
    41  	if r.started {
    42  		return
    43  	}
    44  	r.stopLock.Lock()
    45  	defer r.stopLock.Unlock()
    46  	go r.run()
    47  	r.started = true
    48  }
    49  
    50  // Started returns if the check runner has started running
    51  func (r *CheckRunner) Started() bool {
    52  	r.startedLock.Lock()
    53  	defer r.startedLock.Unlock()
    54  	return r.started
    55  }
    56  
    57  // Stop is used to stop the check.
    58  func (r *CheckRunner) Stop() {
    59  	r.stopLock.Lock()
    60  	defer r.stopLock.Unlock()
    61  	if !r.stop {
    62  		r.stop = true
    63  		close(r.stopCh)
    64  	}
    65  }
    66  
    67  // run is invoked by a goroutine to run until Stop() is called
    68  func (r *CheckRunner) run() {
    69  	// Get the randomized initial pause time
    70  	initialPauseTime := lib.RandomStagger(r.check.Interval())
    71  	r.logger.Printf("[DEBUG] agent: pausing %v before first invocation of %s", initialPauseTime, r.check.ID())
    72  	next := time.NewTimer(initialPauseTime)
    73  	for {
    74  		select {
    75  		case <-next.C:
    76  			r.runCheck(r.check)
    77  			next.Reset(r.check.Interval())
    78  		case <-r.stopCh:
    79  			next.Stop()
    80  			return
    81  		}
    82  	}
    83  }
    84  
    85  // Check is an interface which check providers can implement for Nomad to run
    86  type Check interface {
    87  	Run() *cstructs.CheckResult
    88  	ID() string
    89  	Interval() time.Duration
    90  	Timeout() time.Duration
    91  }