Commit c3c44c90 authored by Adin Schmahmann's avatar Adin Schmahmann

backoff strategy factory constructors take random seeds instead of random sources

parent 9ad0e778
......@@ -3,6 +3,7 @@ package discovery
import (
"math"
"math/rand"
"sync"
"time"
)
......@@ -90,7 +91,8 @@ func (b *fixedBackoff) Reset() {}
// timeUnits are the units of time the polynomial is evaluated in
// polyCoefs is the array of polynomial coefficients from [c0, c1, ... cn]
func NewPolynomialBackoff(min, max time.Duration, jitter Jitter,
timeUnits time.Duration, polyCoefs []float64, rng *rand.Rand) BackoffFactory {
timeUnits time.Duration, polyCoefs []float64, rngSeed int64) BackoffFactory {
rng := rand.New(&lockedSource{src: rand.NewSource(rngSeed)})
return func() BackoffStrategy {
return &polynomialBackoff{
attemptBackoff: attemptBackoff{
......@@ -138,7 +140,8 @@ func (b *polynomialBackoff) Delay() time.Duration {
// jitter is the function for adding randomness around the backoff
// timeUnits are the units of time the base^x is evaluated in
func NewExponentialBackoff(min, max time.Duration, jitter Jitter,
timeUnits time.Duration, base float64, offset time.Duration, rng *rand.Rand) BackoffFactory {
timeUnits time.Duration, base float64, offset time.Duration, rngSeed int64) BackoffFactory {
rng := rand.New(&lockedSource{src: rand.NewSource(rngSeed)})
return func() BackoffStrategy {
return &exponentialBackoff{
attemptBackoff: attemptBackoff{
......@@ -173,7 +176,8 @@ func (b *exponentialBackoff) Delay() time.Duration {
// NewExponentialDecorrelatedJitter creates a BackoffFactory with backoff of the roughly of the form base^x where x is the attempt number.
// Delays start at the minimum duration and after each attempt delay = rand(min, delay * base), bounded by the max
// See https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/ for more information
func NewExponentialDecorrelatedJitter(min, max time.Duration, base float64, rng *rand.Rand) BackoffFactory {
func NewExponentialDecorrelatedJitter(min, max time.Duration, base float64, rngSeed int64) BackoffFactory {
rng := rand.New(&lockedSource{src: rand.NewSource(rngSeed)})
return func() BackoffStrategy {
return &exponentialDecorrelatedJitter{
randomizedBackoff: randomizedBackoff{
......@@ -204,3 +208,21 @@ func (b *exponentialDecorrelatedJitter) Delay() time.Duration {
}
func (b *exponentialDecorrelatedJitter) Reset() { b.lastDelay = 0 }
type lockedSource struct {
lk sync.Mutex
src rand.Source
}
func (r *lockedSource) Int63() (n int64) {
r.lk.Lock()
n = r.src.Int63()
r.lk.Unlock()
return
}
func (r *lockedSource) Seed(seed int64) {
r.lk.Lock()
r.src.Seed(seed)
r.lk.Unlock()
}
......@@ -39,8 +39,7 @@ func TestFixedBackoff(t *testing.T) {
}
func TestPolynomialBackoff(t *testing.T) {
rng := rand.New(rand.NewSource(0))
bkf := NewPolynomialBackoff(time.Second, time.Second*33, NoJitter, time.Second, []float64{0.5, 2, 3}, rng)
bkf := NewPolynomialBackoff(time.Second, time.Second*33, NoJitter, time.Second, []float64{0.5, 2, 3}, 0)
b1 := bkf()
b2 := bkf()
......@@ -59,8 +58,7 @@ func TestPolynomialBackoff(t *testing.T) {
}
func TestExponentialBackoff(t *testing.T) {
rng := rand.New(rand.NewSource(0))
bkf := NewExponentialBackoff(time.Millisecond*650, time.Second*7, NoJitter, time.Second, 1.5, -time.Millisecond*400, rng)
bkf := NewExponentialBackoff(time.Millisecond*650, time.Second*7, NoJitter, time.Second, 1.5, -time.Millisecond*400, 0)
b1 := bkf()
b2 := bkf()
......
......@@ -67,7 +67,7 @@ func TestBackoffDiscoverySingleBackoff(t *testing.T) {
d2 := &mockDiscoveryClient{h2, discServer}
bkf := NewExponentialBackoff(time.Millisecond*100, time.Second*10, NoJitter,
time.Millisecond*100, 2.5, 0, nil)
time.Millisecond*100, 2.5, 0, 0)
dCache, err := NewBackoffDiscovery(d1, bkf)
if err != nil {
t.Fatal(err)
......@@ -101,7 +101,7 @@ func TestBackoffDiscoveryMultipleBackoff(t *testing.T) {
// Startup delay is 0ms. First backoff after finding data is 100ms, second backoff is 250ms.
bkf := NewExponentialBackoff(time.Millisecond*100, time.Second*10, NoJitter,
time.Millisecond*100, 2.5, 0, nil)
time.Millisecond*100, 2.5, 0, 0)
dCache, err := NewBackoffDiscovery(d1, bkf)
if err != nil {
t.Fatal(err)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment