Skip to content

Commit f8797fc

Browse files
committed
chore!: add arg to retry.ExponentialBackoff option
1 parent 0abe543 commit f8797fc

File tree

5 files changed

+46
-24
lines changed

5 files changed

+46
-24
lines changed

rolling-shutter/collator/epochhandling.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (c *collator) sendDecryptionTriggers(ctx context.Context) error {
140140
err := c.p2p.SendMessage(ctx,
141141
msg,
142142
retry.Interval(time.Second),
143-
retry.ExponentialBackoff(),
143+
retry.ExponentialBackoff(nil),
144144
retry.NumberOfRetries(3),
145145
retry.LogIdentifier(msg.LogInfo()),
146146
)
Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package retry
22

33
import (
4+
"errors"
45
"time"
56

67
"github.com/benbjohnson/clock"
@@ -13,51 +14,64 @@ import (
1314
// `-1` is a special value that results in
1415
// infinite retries.
1516
func NumberOfRetries(n int) Option {
16-
return func(r *retrier) {
17+
return func(r *retrier) error {
1718
r.numRetries = n
1819
if n == -1 {
1920
r.infiniteRetries = true
2021
}
22+
return nil
2123
}
2224
}
2325

2426
func MaxInterval(t time.Duration) Option {
25-
return func(r *retrier) {
27+
return func(r *retrier) error {
2628
r.maxInterval = t
29+
return nil
2730
}
2831
}
2932

3033
func Interval(t time.Duration) Option {
31-
return func(r *retrier) {
34+
return func(r *retrier) error {
3235
r.interval = t
36+
return nil
3337
}
3438
}
3539

3640
func StopOnErrors(e ...error) Option {
37-
return func(r *retrier) {
41+
return func(r *retrier) error {
3842
r.cancelingErrors = e
43+
return nil
3944
}
4045
}
4146

42-
func ExponentialBackoff() Option {
43-
return func(r *retrier) {
44-
// for now just use a fixed value
45-
r.multiplier = 1.5
47+
func ExponentialBackoff(multiplier *float64) Option {
48+
return func(r *retrier) error {
49+
if multiplier == nil {
50+
r.multiplier = 1.5
51+
return nil
52+
}
53+
r.multiplier = *multiplier
54+
if r.multiplier <= 1.0 {
55+
return errors.New("can't use value <=1.0 as exponential multiplier")
56+
}
57+
return nil
4658
}
4759
}
4860

4961
func LogIdentifier(s string) Option {
5062
id := uuid.NewString()
51-
return func(r *retrier) {
63+
return func(r *retrier) error {
5264
r.zlogContext = r.zlogContext.Str("id", id+":"+s)
65+
return nil
5366
}
5467
}
5568

5669
// UseClock injects a different `clock.Clock`
5770
// implementation than the default `time`
5871
// wrapper. Mainly used for mocking.
5972
func UseClock(c clock.Clock) Option {
60-
return func(r *retrier) {
73+
return func(r *retrier) error {
6174
r.clock = c
75+
return nil
6276
}
6377
}

rolling-shutter/medley/retry/retry.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/benbjohnson/clock"
8+
"github.com/pkg/errors"
89
"github.com/rs/zerolog"
910
"github.com/rs/zerolog/log"
1011

@@ -38,10 +39,14 @@ func newRetrier() *retrier {
3839
}
3940
}
4041

41-
func (r *retrier) option(opts []Option) {
42+
func (r *retrier) applyOptions(opts []Option) error {
4243
for _, opt := range opts {
43-
opt(r)
44+
err := opt(r)
45+
if err != nil {
46+
return err
47+
}
4448
}
49+
return nil
4550
}
4651

4752
func (r *retrier) iterator(next <-chan time.Time) <-chan time.Time {
@@ -74,15 +79,20 @@ func (r *retrier) iterator(next <-chan time.Time) <-chan time.Time {
7479
}
7580

7681
type (
77-
Option func(*retrier)
82+
Option func(*retrier) error
7883
RetriableFunction[T any] func(ctx context.Context) (T, error)
7984
)
8085

8186
// FunctionCall calls the given function multiple times until it doesn't return an error
8287
// or one of any optional, user-defined specific errors is returned.
8388
func FunctionCall[T any](ctx context.Context, fn RetriableFunction[T], opts ...Option) (T, error) {
89+
var err error
90+
var null T
91+
8492
retrier := newRetrier()
85-
retrier.option(opts)
93+
if err := retrier.applyOptions(opts); err != nil {
94+
return null, errors.Wrap(err, "apply options")
95+
}
8696
funcName := introspection.GetFuncName(4)
8797
retrier.zlogContext = retrier.zlogContext.Str("funcName", funcName)
8898
logger := retrier.zlogContext.Logger()
@@ -91,9 +101,6 @@ func FunctionCall[T any](ctx context.Context, fn RetriableFunction[T], opts ...O
91101

92102
retry := retrier.iterator(next)
93103

94-
var err error
95-
var null T
96-
97104
callCount := 0
98105

99106
for {

rolling-shutter/medley/retry/retry_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ var testFlagTable = []testFlags{
6363
[]Option{
6464
Interval(baseInterval),
6565
NumberOfRetries(5),
66-
ExponentialBackoff(),
66+
ExponentialBackoff(nil),
6767
},
6868
errDefault,
6969
[]time.Duration{
@@ -83,7 +83,7 @@ var testFlagTable = []testFlags{
8383
MaxInterval(
8484
multDuration(baseInterval, math.Pow(1.5, 2)),
8585
),
86-
ExponentialBackoff(),
86+
ExponentialBackoff(nil),
8787
},
8888
errDefault,
8989
[]time.Duration{

rolling-shutter/p2p/bootstrap.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,14 @@ func bootstrap(
8282
// A bootstrap node is not required to connect to other bootstrap nodes.
8383
// If however we did configure a list of bootstrap nodes,
8484
// we should try a long time to connect to at least one other bootstrapper first.
85+
backoffMult := float64(1.01)
8586
_, err := retry.FunctionCall(
8687
ctx,
8788
f,
88-
retry.MaxInterval(5*time.Hour),
89+
retry.MaxInterval(1*time.Minute),
8990
retry.StopOnErrors(errInsufficientBootstrpConfigured),
90-
retry.Interval(2*time.Minute))
91+
retry.Interval(2*time.Second),
92+
retry.ExponentialBackoff(&backoffMult))
9193
if err != nil {
9294
log.Error().Err(err).
9395
Msg("failed to bootstrap, continuing without peer connections.")
@@ -96,9 +98,8 @@ func bootstrap(
9698
_, err := retry.FunctionCall(
9799
ctx,
98100
f,
99-
retry.MaxInterval(5*time.Minute),
100101
retry.StopOnErrors(errInsufficientBootstrpConfigured),
101-
retry.Interval(30*time.Second))
102+
retry.Interval(2*time.Second))
102103
if err != nil {
103104
// For normal peers, after trying some time it is reasonable to halt.
104105
// If we don't get an initial connection to a bootsrap node,

0 commit comments

Comments
 (0)