open-nomad/client/restarts.go

72 lines
1.8 KiB
Go
Raw Normal View History

package client
import (
2015-12-17 18:37:53 +00:00
"math/rand"
"time"
"github.com/hashicorp/nomad/nomad/structs"
)
2015-12-18 20:11:12 +00:00
// jitter is the percent of jitter added to restart delays.
const jitter = 0.25
2015-12-16 22:39:37 +00:00
func newRestartTracker(policy *structs.RestartPolicy) *RestartTracker {
2015-12-18 20:17:13 +00:00
return &RestartTracker{
startTime: time.Now(),
policy: policy,
2015-12-17 18:37:53 +00:00
rand: rand.New(rand.NewSource(time.Now().Unix())),
}
}
2015-12-18 20:17:13 +00:00
type RestartTracker struct {
count int // Current number of attempts.
startTime time.Time // When the interval began
policy *structs.RestartPolicy
2015-12-17 18:37:53 +00:00
rand *rand.Rand
}
2015-12-18 20:17:13 +00:00
func (r *RestartTracker) NextRestart(exitCode int) (bool, time.Duration) {
// Check if we have entered a new interval.
end := r.startTime.Add(r.policy.Interval)
now := time.Now()
if now.After(end) {
r.count = 0
r.startTime = now
2015-12-17 18:37:53 +00:00
return true, r.jitter()
2015-12-18 20:17:13 +00:00
}
2015-12-18 20:17:13 +00:00
r.count++
2015-12-18 20:17:13 +00:00
// If we are under the attempts, restart with delay.
if r.count <= r.policy.Attempts {
2015-12-17 18:37:53 +00:00
return r.shouldRestart(exitCode), r.jitter()
}
2015-12-18 20:17:13 +00:00
// Don't restart since mode is "fail"
if r.policy.Mode == structs.RestartPolicyModeFail {
return false, 0
}
2015-12-18 20:17:13 +00:00
// Apply an artifical wait to enter the next interval
return r.shouldRestart(exitCode), end.Sub(now)
}
2015-12-18 20:17:13 +00:00
// shouldRestart returns whether a restart should occur based on the exit code
// and the RestartOnSuccess configuration.
func (r *RestartTracker) shouldRestart(exitCode int) bool {
2015-12-17 18:37:53 +00:00
return exitCode != 0 || r.policy.RestartOnSuccess
}
// jitter returns the delay time plus a jitter.
func (r *RestartTracker) jitter() time.Duration {
d := r.policy.Delay.Nanoseconds()
2015-12-18 20:11:12 +00:00
j := float64(r.rand.Int63n(d)) * jitter
return time.Duration(d + int64(j))
}
2015-12-18 20:17:13 +00:00
// Returns a tracker that never restarts.
func noRestartsTracker() *RestartTracker {
policy := &structs.RestartPolicy{Attempts: 0, Mode: structs.RestartPolicyModeFail}
2015-12-16 22:39:37 +00:00
return newRestartTracker(policy)
}