From ef55ba657f40c17031b945dbe7da249bf31f8b10 Mon Sep 17 00:00:00 2001 From: David Arroyo Date: Sun, 21 Jun 2015 23:06:33 -0400 Subject: [PATCH] Add Fibonacci strategy --- retry.go | 15 +++++++++++++++ retry_test.go | 30 ++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/retry.go b/retry.go index ad9f818..15f2129 100644 --- a/retry.go +++ b/retry.go @@ -51,6 +51,21 @@ func init() { // capture the most common use cases. type Strategy func(nth int) time.Duration +// Fibonacci creates a Strategy that returns fib(n) units, where +// fib is the fibonacci function, f(n) = f(n-1) + f(n-2). +func Fibonacci(units time.Duration) Strategy { + return func(n int) time.Duration { + f := [...]time.Duration{1,0} + if n <= 0 { + return 0 + } + for i := 1; i < n; i++ { + f[0], f[1] = f[0] + f[1], f[0] + } + return f[0] * units + } +} + // Exponential creates an exponential backoff Strategy that returns // 2ⁿ units. The values returned by Exponential will increase up to // the maximum value of time.Duration and will not overflow. diff --git a/retry_test.go b/retry_test.go index 0fc5df2..a518791 100644 --- a/retry_test.go +++ b/retry_test.go @@ -34,16 +34,30 @@ func TestExponentialBackoff(t *testing.T) { } } +func TestFibonacciBackoff(t *testing.T) { + ans := []time.Duration{0, 1, 1, 2, 3, 5, 8, 13, 21, 34} + backoff := Fibonacci(1) + for i, v := range ans { + if x := backoff(i); x != v { + t.Errorf("fibonacci backoff(%d) = %s, should be %s", i, x, v) + } else { + t.Logf("fibonacci backoff(%d) = %s", i, x) + } + } + if backoff(-1) != 0 { + t.Errorf("fibonacci backoff(-1) = %s, should be 0ns", backoff(-1)) + } +} + func TestIntervalBackoff(t *testing.T) { - x := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} - const jitter = 50 - backoff := Seconds(x...) + ans := []time.Duration{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + backoff := Intervals(ans...) - for i, v := range x { - t.Logf("fixed backoff(%d) = %s", i, backoff(i)) - if backoff(i) != time.Duration(v)*time.Second { - t.Errorf("fixed backoff(%d) = %s, should be > %s", i, backoff(i), - time.Duration(v)*time.Second) + for i, v := range ans { + if x := backoff(i); x != v { + t.Errorf("fixed backoff(%d) = %s, should be %s", i, x, v) + } else { + t.Logf("fixed backoff(%d) = %s", i, x) } } }