Skip to content

Commit

Permalink
add retry.Do0 (#12194)
Browse files Browse the repository at this point in the history
* add retry.Do0

* update code to use Do0
  • Loading branch information
zhiqiangxu authored Sep 29, 2024
1 parent cd7e9d4 commit f2d5e32
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 11 deletions.
5 changes: 2 additions & 3 deletions op-node/node/conductor.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,11 @@ func (c *ConductorClient) CommitUnsafePayload(ctx context.Context, payload *eth.
ctx, cancel := context.WithTimeout(ctx, c.cfg.ConductorRpcTimeout)
defer cancel()

// extra bool return value is required for the generic, can be ignored.
_, err := retry.Do(ctx, 2, retry.Fixed(50*time.Millisecond), func() (bool, error) {
err := retry.Do0(ctx, 2, retry.Fixed(50*time.Millisecond), func() error {
record := c.metrics.RecordRPCClientRequest("conductor_commitUnsafePayload")
err := c.apiClient.CommitUnsafePayload(ctx, payload)
record(err)
return true, err
return err
})
return err
}
Expand Down
6 changes: 3 additions & 3 deletions op-node/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,12 @@ func (n *OpNode) initRuntimeConfig(ctx context.Context, cfg *Config) error {
}

// initialize the runtime config before unblocking
if _, err := retry.Do(ctx, 5, retry.Fixed(time.Second*10), func() (eth.L1BlockRef, error) {
ref, err := reload(ctx)
if err := retry.Do0(ctx, 5, retry.Fixed(time.Second*10), func() error {
_, err := reload(ctx)
if errors.Is(err, errNodeHalt) { // don't retry on halt error
err = nil
}
return ref, err
return err
}); err != nil {
return fmt.Errorf("failed to load runtime configuration repeatedly, last error: %w", err)
}
Expand Down
23 changes: 18 additions & 5 deletions op-service/retry/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,38 @@ func Do2[T, U any](ctx context.Context, maxAttempts int, strategy Strategy, op f
// Strategy.
func Do[T any](ctx context.Context, maxAttempts int, strategy Strategy, op func() (T, error)) (T, error) {
var empty, ret T
f := func() (err error) {
ret, err = op()
return
}
err := Do0(ctx, maxAttempts, strategy, f)
if err != nil {
return empty, err
}
return ret, err
}

// Do0 is similar to Do and Do2, execept that `op` only returns an error
func Do0(ctx context.Context, maxAttempts int, strategy Strategy, op func() error) error {
var err error
if maxAttempts < 1 {
return empty, fmt.Errorf("need at least 1 attempt to run op, but have %d max attempts", maxAttempts)
return fmt.Errorf("need at least 1 attempt to run op, but have %d max attempts", maxAttempts)
}

for i := 0; i < maxAttempts; i++ {
if ctx.Err() != nil {
return empty, ctx.Err()
return ctx.Err()
}
ret, err = op()
err = op()
if err == nil {
return ret, nil
return nil
}
// Don't sleep when we are about to exit the loop & return ErrFailedPermanently
if i != maxAttempts-1 {
time.Sleep(strategy.Duration(i))
}
}
return empty, &ErrFailedPermanently{
return &ErrFailedPermanently{
attempts: maxAttempts,
LastErr: err,
}
Expand Down

0 comments on commit f2d5e32

Please sign in to comment.