diff --git a/client/client.go b/client/client.go index 1c32e13e1..eecb27d9f 100644 --- a/client/client.go +++ b/client/client.go @@ -13,8 +13,7 @@ import ( "time" "github.com/armon/go-metrics" - "github.com/mitchellh/hashstructure" - + "github.com/hashicorp/consul/lib" "github.com/hashicorp/go-multierror" "github.com/hashicorp/nomad/client/allocdir" "github.com/hashicorp/nomad/client/config" @@ -24,6 +23,7 @@ import ( "github.com/hashicorp/nomad/client/stats" "github.com/hashicorp/nomad/nomad" "github.com/hashicorp/nomad/nomad/structs" + "github.com/mitchellh/hashstructure" ) const ( @@ -785,7 +785,7 @@ func (c *Client) retryIntv(base time.Duration) time.Duration { if c.config.DevMode { return devModeRetryIntv } - return base + randomStagger(base) + return base + lib.RandomStagger(base) } // registerAndHeartbeat is a long lived goroutine used to register the client @@ -804,7 +804,7 @@ func (c *Client) registerAndHeartbeat() { if c.config.DevMode { heartbeat = time.After(0) } else { - heartbeat = time.After(randomStagger(initialHeartbeatStagger)) + heartbeat = time.After(lib.RandomStagger(initialHeartbeatStagger)) } for { diff --git a/client/consul/check.go b/client/consul/check.go index 052c5c78c..28df291f6 100644 --- a/client/consul/check.go +++ b/client/consul/check.go @@ -2,10 +2,10 @@ package consul import ( "log" - "math/rand" "sync" "time" + "github.com/hashicorp/consul/lib" cstructs "github.com/hashicorp/nomad/client/driver/structs" ) @@ -60,7 +60,7 @@ func (r *CheckRunner) Stop() { // run is invoked by a goroutine to run until Stop() is called func (r *CheckRunner) run() { // Get the randomized initial pause time - initialPauseTime := randomStagger(r.check.Interval()) + initialPauseTime := lib.RandomStagger(r.check.Interval()) r.logger.Printf("[DEBUG] agent: pausing %v before first invocation of %s", initialPauseTime, r.check.ID()) next := time.NewTimer(initialPauseTime) for { @@ -82,8 +82,3 @@ type Check interface { Interval() time.Duration Timeout() time.Duration } - -// 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)) -} diff --git a/client/util.go b/client/util.go index a8afcd171..b04f173f0 100644 --- a/client/util.go +++ b/client/util.go @@ -7,7 +7,6 @@ import ( "math/rand" "os" "path/filepath" - "time" "github.com/hashicorp/nomad/nomad/structs" ) @@ -69,11 +68,6 @@ func diffAllocs(existing []*structs.Allocation, allocs *allocUpdates) *diffResul return result } -// 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)) -} - // shuffleStrings randomly shuffles the list of strings func shuffleStrings(list []string) { for i := range list { diff --git a/client/util_test.go b/client/util_test.go index 431a93f6b..c0a8633c3 100644 --- a/client/util_test.go +++ b/client/util_test.go @@ -6,7 +6,6 @@ import ( "path/filepath" "reflect" "testing" - "time" "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" @@ -56,17 +55,6 @@ func TestDiffAllocs(t *testing.T) { } } -func TestRandomStagger(t *testing.T) { - t.Parallel() - intv := time.Minute - for i := 0; i < 10; i++ { - stagger := randomStagger(intv) - if stagger < 0 || stagger >= intv { - t.Fatalf("Bad: %v", stagger) - } - } -} - func TestShuffleStrings(t *testing.T) { t.Parallel() // Generate input diff --git a/command/agent/command.go b/command/agent/command.go index 5c8371b79..129bb2398 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -16,6 +16,7 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/hashicorp/consul/lib" "github.com/hashicorp/go-checkpoint" "github.com/hashicorp/go-syslog" "github.com/hashicorp/logutils" @@ -334,7 +335,7 @@ func (c *Command) setupAgent(config *Config, logOutput io.Writer) error { // Do an immediate check within the next 30 seconds go func() { - time.Sleep(randomStagger(30 * time.Second)) + time.Sleep(lib.RandomStagger(30 * time.Second)) c.checkpointResults(checkpoint.Check(updateParams)) }() } diff --git a/command/agent/util.go b/command/agent/util.go index 2fa4993ae..c74fe645c 100644 --- a/command/agent/util.go +++ b/command/agent/util.go @@ -2,16 +2,9 @@ package agent import ( "fmt" - "math/rand" "net" - "time" ) -// 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)) -} - // IpOfDevice returns a routable ip addr of a device func ipOfDevice(name string) (net.IP, error) { intf, err := net.InterfaceByName(name) diff --git a/command/agent/util_test.go b/command/agent/util_test.go deleted file mode 100644 index e31943a20..000000000 --- a/command/agent/util_test.go +++ /dev/null @@ -1,16 +0,0 @@ -package agent - -import ( - "testing" - "time" -) - -func TestRandomStagger(t *testing.T) { - intv := time.Minute - for i := 0; i < 10; i++ { - stagger := randomStagger(intv) - if stagger < 0 || stagger >= intv { - t.Fatalf("Bad: %v", stagger) - } - } -} diff --git a/nomad/heartbeat.go b/nomad/heartbeat.go index aed47d4bd..3102b7320 100644 --- a/nomad/heartbeat.go +++ b/nomad/heartbeat.go @@ -51,7 +51,7 @@ func (s *Server) resetHeartbeatTimer(id string) (time.Duration, error) { // Compute the target TTL value n := len(s.heartbeatTimers) ttl := lib.RateScaledInterval(s.config.MaxHeartbeatsPerSecond, s.config.MinHeartbeatTTL, n) - ttl += randomStagger(ttl) + ttl += lib.RandomStagger(ttl) // Reset the TTL s.resetHeartbeatTimerLocked(id, ttl+s.config.HeartbeatGrace) diff --git a/nomad/rpc.go b/nomad/rpc.go index a25566f11..2080737c3 100644 --- a/nomad/rpc.go +++ b/nomad/rpc.go @@ -11,6 +11,7 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/hashicorp/consul/lib" "github.com/hashicorp/net-rpc-msgpackrpc" "github.com/hashicorp/nomad/nomad/state" "github.com/hashicorp/nomad/nomad/structs" @@ -308,7 +309,7 @@ func (s *Server) blockingRPC(opts *blockingOptions) error { } // Apply a small amount of jitter to the request - opts.queryOpts.MaxQueryTime += randomStagger(opts.queryOpts.MaxQueryTime / jitterFraction) + opts.queryOpts.MaxQueryTime += lib.RandomStagger(opts.queryOpts.MaxQueryTime / jitterFraction) // Setup a query timeout timeout = time.NewTimer(opts.queryOpts.MaxQueryTime) diff --git a/nomad/util.go b/nomad/util.go index 961c75ab6..8bc3fb7d7 100644 --- a/nomad/util.go +++ b/nomad/util.go @@ -10,7 +10,6 @@ import ( "path/filepath" "runtime" "strconv" - "time" crand "crypto/rand" @@ -101,11 +100,6 @@ func isNomadServer(m serf.Member) (bool, *serverParts) { return true, parts } -// 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)) -} - // shuffleStrings randomly shuffles the list of strings func shuffleStrings(list []string) { for i := range list { diff --git a/nomad/util_test.go b/nomad/util_test.go index e71b0efef..e415bb4c9 100644 --- a/nomad/util_test.go +++ b/nomad/util_test.go @@ -4,7 +4,6 @@ import ( "net" "reflect" "testing" - "time" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/serf/serf" @@ -57,16 +56,6 @@ func TestIsNomadServer(t *testing.T) { } } -func TestRandomStagger(t *testing.T) { - intv := time.Minute - for i := 0; i < 10; i++ { - stagger := randomStagger(intv) - if stagger < 0 || stagger >= intv { - t.Fatalf("Bad: %v", stagger) - } - } -} - func TestShuffleStrings(t *testing.T) { // Generate input inp := make([]string, 10)