Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Factory, FactoryFunc interfaces #103

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions backoff.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ func (b *ZeroBackOff) Reset() {}

func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 }

func (b *ZeroBackOff) NewBackOff() BackOff {
copy := *b
return &copy
}

// StopBackOff is a fixed backoff policy that always returns backoff.Stop for
// NextBackOff(), meaning that the operation should never be retried.
type StopBackOff struct{}
Expand All @@ -51,6 +56,11 @@ func (b *StopBackOff) Reset() {}

func (b *StopBackOff) NextBackOff() time.Duration { return Stop }

func (b *StopBackOff) NewBackOff() BackOff {
copy := *b
return &copy
}

// ConstantBackOff is a backoff policy that always returns the same backoff delay.
// This is in contrast to an exponential backoff policy,
// which returns a delay that grows longer as you call NextBackOff() over and over again.
Expand All @@ -60,6 +70,10 @@ type ConstantBackOff struct {

func (b *ConstantBackOff) Reset() {}
func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval }
func (b *ConstantBackOff) NewBackOff() BackOff {
copy := *b
return &copy
}

func NewConstantBackOff(d time.Duration) *ConstantBackOff {
return &ConstantBackOff{Interval: d}
Expand Down
32 changes: 32 additions & 0 deletions backoff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,41 @@ func subtestNextBackOff(t *testing.T, expectedValue time.Duration, backOffPolicy
}
}

func TestStopBackOff(t *testing.T) {
backoff := &StopBackOff{}

backoffCpy := backoff.NewBackOff()
_, ok := backoffCpy.(*StopBackOff)
if !ok {
t.Error("wrong type from NewBackOff")
}
}

func TestZeroBackOff(t *testing.T) {
backoff := &ZeroBackOff{}

backoffCpy := backoff.NewBackOff()
_, ok := backoffCpy.(*ZeroBackOff)
if !ok {
t.Error("wrong type from NewBackOff")
}
}

func TestConstantBackOff(t *testing.T) {
backoff := NewConstantBackOff(time.Second)
if backoff.NextBackOff() != time.Second {
t.Error("invalid interval")
}

backoffCpy := backoff.NewBackOff()
constant, ok := backoffCpy.(*ConstantBackOff)
if !ok {
t.Error("wrong type from NewBackOff")
}

if constant == backoff {
t.Error("returned backoff is the same as original")
}

assertEquals(t, backoff.Interval, constant.Interval)
}
6 changes: 6 additions & 0 deletions exponential.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,9 @@ func getRandomValueFromInterval(randomizationFactor, random float64, currentInte
// we want a 33% chance for selecting either 1, 2 or 3.
return time.Duration(minInterval + (random * (maxInterval - minInterval + 1)))
}

// NewBackOff implements Factory, and returns a copy of the exponential backoff
func (b *ExponentialBackOff) NewBackOff() BackOff {
copy := *b
return &copy
}
31 changes: 31 additions & 0 deletions exponential_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,34 @@ func assertEquals(t *testing.T, expected, value time.Duration) {
t.Errorf("got: %d, expected: %d", value, expected)
}
}

func TestNewBackOff(t *testing.T) {
var (
testInitialInterval = 500 * time.Millisecond
testRandomizationFactor = 0.1
testMultiplier = 2.0
testMaxInterval = 5 * time.Second
testMaxElapsedTime = 15 * time.Minute
)

exp := NewExponentialBackOff()
exp.InitialInterval = testInitialInterval
exp.RandomizationFactor = testRandomizationFactor
exp.Multiplier = testMultiplier
exp.MaxInterval = testMaxInterval
exp.MaxElapsedTime = testMaxElapsedTime

expCpy := exp.NewBackOff()
exp2, ok := expCpy.(*ExponentialBackOff)
if !ok {
t.Error("wrong type from NewBackoff")
}

if exp2 == exp {
t.Error("returned backoff is the same as original")
}

if *exp2 != *exp {
t.Error("backoff copy was not equal to base backoff")
}
}
14 changes: 14 additions & 0 deletions factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package backoff

// A Factory creates and returns a new backoff policy
type Factory interface {
NewBackOff() BackOff
}

// FactoryFunc is a function that returns a new backoff policy
type FactoryFunc func() BackOff

// NewBackOff implements Factory, allowing a FactoryFunc to be passed to anyywhere that accepts a Factory
func (ff FactoryFunc) NewBackOff() BackOff {
return ff()
}
22 changes: 22 additions & 0 deletions factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package backoff

import "testing"

func TestFactoryFunc(t *testing.T) {
backoff := NewExponentialBackOff()

ff := FactoryFunc(func() BackOff {
return backoff
})

newBackOff := ff.NewBackOff()

expontential, ok := newBackOff.(*ExponentialBackOff)
if !ok {
t.Error("wrong type from NewBackOff")
}

if *expontential != *backoff {
t.Error("backoff was not equal to expected backoff")
}
}