mirror of https://github.com/status-im/consul.git
Guard against divide by zero in lib.RandomStagger()
While I'm at it, add a DurationMinusBufferDomain() function to calculate the min/max for a given call to DurationMinusBuffer() in order to keep the implementation details self-contained.
This commit is contained in:
parent
3a6be9cab0
commit
da298f527d
|
@ -10,12 +10,32 @@ import (
|
||||||
// servicing Consul TTL Checks in advance of the TTL.
|
// servicing Consul TTL Checks in advance of the TTL.
|
||||||
func DurationMinusBuffer(intv time.Duration, buffer time.Duration, jitter int64) time.Duration {
|
func DurationMinusBuffer(intv time.Duration, buffer time.Duration, jitter int64) time.Duration {
|
||||||
d := intv - buffer
|
d := intv - buffer
|
||||||
d -= RandomStagger(time.Duration(int64(d) / jitter))
|
if jitter == 0 {
|
||||||
|
d -= RandomStagger(d)
|
||||||
|
} else {
|
||||||
|
d -= RandomStagger(time.Duration(int64(d) / jitter))
|
||||||
|
}
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DurationMinusBufferDomain returns the domain of valid durations from a
|
||||||
|
// call to DurationMinusBuffer. This function is used to check user
|
||||||
|
// specified input values to DurationMinusBuffer.
|
||||||
|
func DurationMinusBufferDomain(intv time.Duration, buffer time.Duration, jitter int64) (min time.Duration, max time.Duration) {
|
||||||
|
max = intv - buffer
|
||||||
|
if jitter == 0 {
|
||||||
|
min = max
|
||||||
|
} else {
|
||||||
|
min = max - time.Duration(int64(max)/jitter)
|
||||||
|
}
|
||||||
|
return min, max
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a random stagger interval between 0 and the duration
|
// Returns a random stagger interval between 0 and the duration
|
||||||
func RandomStagger(intv time.Duration) time.Duration {
|
func RandomStagger(intv time.Duration) time.Duration {
|
||||||
|
if intv == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
return time.Duration(uint64(rand.Int63()) % uint64(intv))
|
return time.Duration(uint64(rand.Int63()) % uint64(intv))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,123 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDurationMinusBuffer(t *testing.T) {
|
func TestDurationMinusBuffer(t *testing.T) {
|
||||||
const (
|
tests := []struct {
|
||||||
buffer = 10 * time.Second
|
Duration time.Duration
|
||||||
jitter = 16
|
Buffer time.Duration
|
||||||
)
|
Jitter int64
|
||||||
intv := 1 * time.Minute
|
}{
|
||||||
minValue := (intv - buffer) - ((intv - buffer) / jitter)
|
{
|
||||||
maxValue := intv - buffer
|
Duration: 1 * time.Minute,
|
||||||
for i := 0; i < 10; i++ {
|
Buffer: 10 * time.Second,
|
||||||
d := DurationMinusBuffer(intv, buffer, jitter)
|
Jitter: 16,
|
||||||
if d < minValue || d > maxValue {
|
},
|
||||||
t.Fatalf("Bad: %v", d)
|
{
|
||||||
|
Duration: 1 * time.Second,
|
||||||
|
Buffer: 500 * time.Millisecond,
|
||||||
|
Jitter: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 1 * time.Second,
|
||||||
|
Buffer: 1 * time.Second,
|
||||||
|
Jitter: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 1 * time.Second,
|
||||||
|
Buffer: 1 * time.Second,
|
||||||
|
Jitter: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 1 * time.Second,
|
||||||
|
Buffer: 1 * time.Second,
|
||||||
|
Jitter: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
min, max := DurationMinusBufferDomain(test.Duration, test.Buffer, test.Jitter)
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
d := DurationMinusBuffer(test.Duration, test.Buffer, test.Jitter)
|
||||||
|
if d < min || d > max {
|
||||||
|
t.Fatalf("Bad: %v", d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDurationMinusBufferDomain(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
Duration time.Duration
|
||||||
|
Buffer time.Duration
|
||||||
|
Jitter int64
|
||||||
|
Min time.Duration
|
||||||
|
Max time.Duration
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Duration: 60 * time.Second,
|
||||||
|
Buffer: 10 * time.Second,
|
||||||
|
Jitter: 16,
|
||||||
|
Min: 46*time.Second + 875*time.Millisecond,
|
||||||
|
Max: 50 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 60 * time.Second,
|
||||||
|
Buffer: 0 * time.Second,
|
||||||
|
Jitter: 16,
|
||||||
|
Min: 56*time.Second + 250*time.Millisecond,
|
||||||
|
Max: 60 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 60 * time.Second,
|
||||||
|
Buffer: 0 * time.Second,
|
||||||
|
Jitter: 0,
|
||||||
|
Min: 60 * time.Second,
|
||||||
|
Max: 60 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 60 * time.Second,
|
||||||
|
Buffer: 0 * time.Second,
|
||||||
|
Jitter: 1,
|
||||||
|
Min: 0 * time.Second,
|
||||||
|
Max: 60 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 60 * time.Second,
|
||||||
|
Buffer: 0 * time.Second,
|
||||||
|
Jitter: 2,
|
||||||
|
Min: 30 * time.Second,
|
||||||
|
Max: 60 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 60 * time.Second,
|
||||||
|
Buffer: 0 * time.Second,
|
||||||
|
Jitter: 4,
|
||||||
|
Min: 45 * time.Second,
|
||||||
|
Max: 60 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 0 * time.Second,
|
||||||
|
Buffer: 0 * time.Second,
|
||||||
|
Jitter: 0,
|
||||||
|
Min: 0 * time.Second,
|
||||||
|
Max: 0 * time.Second,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Duration: 60 * time.Second,
|
||||||
|
Buffer: 120 * time.Second,
|
||||||
|
Jitter: 8,
|
||||||
|
Min: -1 * (52*time.Second + 500*time.Millisecond),
|
||||||
|
Max: -1 * 60 * time.Second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
min, max := DurationMinusBufferDomain(test.Duration, test.Buffer, test.Jitter)
|
||||||
|
if min != test.Min {
|
||||||
|
t.Errorf("Bad min: %v != %v", min, test.Min)
|
||||||
|
}
|
||||||
|
|
||||||
|
if max != test.Max {
|
||||||
|
t.Errorf("Bad max: %v != %v", max, test.Max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue