Skip to content

Commit d833c2e

Browse files
committed
Add some jitter to pkg/retry
... so that a short failure does not trigger a cascade of synchronized retries at exactly the same time. Keep the expected duration of the retry unchanged, vary it 5 % up or down. Signed-off-by: Miloslav Trmač <[email protected]>
1 parent 01126e4 commit d833c2e

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

libimage/manifests/manifests_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -726,17 +726,19 @@ func TestPushManifest(t *testing.T) {
726726
_, _, err = list.Push(ctx, bogusDestRef, options)
727727
assert.Error(t, err)
728728
logString := logBuffer.String()
729-
// Must show warning where libimage is going to retry 5 times with 1s delay
730-
assert.Contains(t, logString, "Failed, retrying in 1s ... (1/5)", "warning not matched")
729+
// Must show warning where libimage is going to retry 5 times with ~1s delay
730+
assert.Regexp(t, `Failed, retrying in \(1\.[0-9]*s\|[0-9].*ms) ... (1/5)`, logString, "warning not matched")
731+
// The 4th delay is approximately 8 seconds.
732+
assert.Regexp(t, `Failed, retrying in [789].[0-9]*s ... (4/5)`, logString, "warning not matched")
731733

732734
logBuffer = bytes.Buffer{}
733735
logrus.SetOutput(&logBuffer)
734736
options.RetryDelay = &delay
735737
_, _, err = list.Push(ctx, bogusDestRef, options)
736738
assert.Error(t, err)
737739
logString = logBuffer.String()
738-
// Must show warning where libimage is going to retry 5 times with 3s delay
739-
assert.Contains(t, logString, "Failed, retrying in 3s ... (1/5)", "warning not matched")
740+
// Must show warning where libimage is going to retry 5 times with ~3s delay
741+
assert.Regexp(t, `Failed, retrying in [23].[0-9]*s ... (1/5)`, logString, "warning not matched")
740742

741743
options.AddCompression = []string{"zstd"}
742744
options.ImageListSelection = cp.CopyAllImages

pkg/retry/retry.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"io"
66
"math"
7+
"math/rand/v2"
78
"net"
89
"net/http"
910
"net/url"
@@ -46,6 +47,7 @@ func IfNecessary(ctx context.Context, operation func() error, options *Options)
4647
if options.Delay != 0 {
4748
delay = options.Delay
4849
}
50+
delay += rand.N(delay/10) - delay/20 // 10 % jitter so that a failure blip doesn’t cause a deterministic stampede
4951
logrus.Warnf("Failed, retrying in %s ... (%d/%d). Error: %v", delay, attempt+1, options.MaxRetry, err)
5052
select {
5153
case <-time.After(delay):

0 commit comments

Comments
 (0)