Skip to content

Commit

Permalink
reconciler: Fix max backoff calculation
Browse files Browse the repository at this point in the history
With enough retry attempts the duration becomes too large
and overflows on conversion to time.Duration leading to negative
durations. Fix this by checking the bounds with a float64 before
conversion.

Signed-off-by: Jussi Maki <[email protected]>
  • Loading branch information
joamaki committed Jul 3, 2024
1 parent 94f6d5d commit 8705921
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
8 changes: 4 additions & 4 deletions reconciler/retries.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ type exponentialBackoff struct {
}

func (e *exponentialBackoff) Duration(attempt int) time.Duration {
dur := time.Duration(float64(e.min) * math.Pow(2, float64(attempt)))
if dur > e.max {
dur = e.max
dur := float64(e.min) * math.Pow(2, float64(attempt))
if dur > float64(e.max) {
return e.max
}
return dur
return time.Duration(dur)
}

func newRetries(minDuration, maxDuration time.Duration, objectToKey func(any) index.Key) *retries {
Expand Down
14 changes: 14 additions & 0 deletions reconciler/retries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/cilium/statedb/index"
)
Expand Down Expand Up @@ -102,5 +103,18 @@ func TestRetries(t *testing.T) {
}
_, ok = rq.Top()
assert.False(t, ok)
}

func TestExponentialBackoff(t *testing.T) {
backoff := exponentialBackoff{
min: time.Millisecond,
max: time.Second,
}

for i := 0; i < 1000; i++ {
dur := backoff.Duration(i)
require.GreaterOrEqual(t, dur, backoff.min)
require.LessOrEqual(t, dur, backoff.max)
}
require.Equal(t, backoff.Duration(0)*2, backoff.Duration(1))
}

0 comments on commit 8705921

Please sign in to comment.