open-nomad/client/consul/check.go

90 lines
1.9 KiB
Go
Raw Normal View History

package consul
import (
2016-03-25 02:00:24 +00:00
"log"
"math/rand"
"sync"
2016-03-24 20:05:08 +00:00
"time"
cstructs "github.com/hashicorp/nomad/client/driver/structs"
)
2016-03-25 04:17:33 +00:00
// CheckRunner runs a given check in a specific interval and update a
2016-03-25 02:30:02 +00:00
// corresponding Consul TTL check
2016-03-25 04:17:33 +00:00
type CheckRunner struct {
2016-03-25 02:00:24 +00:00
check Check
runCheck func(Check)
logger *log.Logger
stop bool
stopCh chan struct{}
stopLock sync.Mutex
2016-03-24 20:05:08 +00:00
2016-03-25 02:00:24 +00:00
started bool
startedLock sync.Mutex
2016-03-24 20:05:08 +00:00
}
2016-03-25 04:17:33 +00:00
// NewCheckRunner configures and returns a CheckRunner
func NewCheckRunner(check Check, runCheck func(Check), logger *log.Logger) *CheckRunner {
cr := CheckRunner{
2016-03-25 02:00:24 +00:00
check: check,
runCheck: runCheck,
logger: logger,
stopCh: make(chan struct{}),
2016-03-24 20:05:08 +00:00
}
return &cr
2016-03-24 20:05:08 +00:00
}
2016-03-25 02:30:02 +00:00
// Start is used to start the check. The check runs until stop is called
2016-03-25 04:17:33 +00:00
func (r *CheckRunner) Start() {
r.startedLock.Lock()
defer r.startedLock.Unlock()
2016-03-25 04:17:33 +00:00
if r.started {
2016-03-25 02:00:24 +00:00
return
2016-03-24 20:05:08 +00:00
}
2016-03-25 04:17:33 +00:00
r.stopLock.Lock()
defer r.stopLock.Unlock()
go r.run()
r.started = true
2016-03-24 20:05:08 +00:00
}
2016-03-25 02:30:02 +00:00
// Stop is used to stop the check.
2016-03-25 04:17:33 +00:00
func (r *CheckRunner) Stop() {
r.stopLock.Lock()
defer r.stopLock.Unlock()
if !r.stop {
r.stop = true
close(r.stopCh)
2016-03-24 20:05:08 +00:00
}
}
2016-03-25 02:00:24 +00:00
// run is invoked by a goroutine to run until Stop() is called
2016-03-25 04:17:33 +00:00
func (r *CheckRunner) run() {
2016-03-25 02:00:24 +00:00
// Get the randomized initial pause time
2016-03-25 04:17:33 +00:00
initialPauseTime := randomStagger(r.check.Interval())
r.logger.Printf("[DEBUG] agent: pausing %v before first invocation of %s", initialPauseTime, r.check.ID())
2016-03-25 23:11:45 +00:00
next := time.NewTimer(initialPauseTime)
2016-03-25 02:00:24 +00:00
for {
select {
2016-03-25 23:11:45 +00:00
case <-next.C:
2016-03-25 04:17:33 +00:00
r.runCheck(r.check)
2016-03-25 23:11:45 +00:00
next.Reset(r.check.Interval())
2016-03-25 04:17:33 +00:00
case <-r.stopCh:
2016-03-25 23:11:45 +00:00
next.Stop()
2016-03-25 02:00:24 +00:00
return
}
2016-03-24 20:05:08 +00:00
}
}
2016-03-25 02:30:02 +00:00
// Check is an interface which check providers can implement for Nomad to run
2016-03-25 02:00:24 +00:00
type Check interface {
Run() *cstructs.CheckResult
ID() string
Interval() time.Duration
Timeout() time.Duration
2016-03-24 20:05:08 +00:00
}
2016-03-25 02:00:24 +00:00
// Returns a random stagger interval between 0 and the duration
func randomStagger(intv time.Duration) time.Duration {
return time.Duration(uint64(rand.Int63()) % uint64(intv))
2016-03-24 20:05:08 +00:00
}