Commit f2d5e32b authored by zhiqiangxu's avatar zhiqiangxu Committed by GitHub

add `retry.Do0` (#12194)

* add retry.Do0

* update code to use Do0
parent cd7e9d40
...@@ -91,12 +91,11 @@ func (c *ConductorClient) CommitUnsafePayload(ctx context.Context, payload *eth. ...@@ -91,12 +91,11 @@ func (c *ConductorClient) CommitUnsafePayload(ctx context.Context, payload *eth.
ctx, cancel := context.WithTimeout(ctx, c.cfg.ConductorRpcTimeout) ctx, cancel := context.WithTimeout(ctx, c.cfg.ConductorRpcTimeout)
defer cancel() defer cancel()
// extra bool return value is required for the generic, can be ignored. err := retry.Do0(ctx, 2, retry.Fixed(50*time.Millisecond), func() error {
_, err := retry.Do(ctx, 2, retry.Fixed(50*time.Millisecond), func() (bool, error) {
record := c.metrics.RecordRPCClientRequest("conductor_commitUnsafePayload") record := c.metrics.RecordRPCClientRequest("conductor_commitUnsafePayload")
err := c.apiClient.CommitUnsafePayload(ctx, payload) err := c.apiClient.CommitUnsafePayload(ctx, payload)
record(err) record(err)
return true, err return err
}) })
return err return err
} }
......
...@@ -262,12 +262,12 @@ func (n *OpNode) initRuntimeConfig(ctx context.Context, cfg *Config) error { ...@@ -262,12 +262,12 @@ func (n *OpNode) initRuntimeConfig(ctx context.Context, cfg *Config) error {
} }
// initialize the runtime config before unblocking // initialize the runtime config before unblocking
if _, err := retry.Do(ctx, 5, retry.Fixed(time.Second*10), func() (eth.L1BlockRef, error) { if err := retry.Do0(ctx, 5, retry.Fixed(time.Second*10), func() error {
ref, err := reload(ctx) _, err := reload(ctx)
if errors.Is(err, errNodeHalt) { // don't retry on halt error if errors.Is(err, errNodeHalt) { // don't retry on halt error
err = nil err = nil
} }
return ref, err return err
}); err != nil { }); err != nil {
return fmt.Errorf("failed to load runtime configuration repeatedly, last error: %w", err) return fmt.Errorf("failed to load runtime configuration repeatedly, last error: %w", err)
} }
......
...@@ -40,25 +40,38 @@ func Do2[T, U any](ctx context.Context, maxAttempts int, strategy Strategy, op f ...@@ -40,25 +40,38 @@ func Do2[T, U any](ctx context.Context, maxAttempts int, strategy Strategy, op f
// Strategy. // Strategy.
func Do[T any](ctx context.Context, maxAttempts int, strategy Strategy, op func() (T, error)) (T, error) { func Do[T any](ctx context.Context, maxAttempts int, strategy Strategy, op func() (T, error)) (T, error) {
var empty, ret T 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 var err error
if maxAttempts < 1 { 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++ { for i := 0; i < maxAttempts; i++ {
if ctx.Err() != nil { if ctx.Err() != nil {
return empty, ctx.Err() return ctx.Err()
} }
ret, err = op() err = op()
if err == nil { if err == nil {
return ret, nil return nil
} }
// Don't sleep when we are about to exit the loop & return ErrFailedPermanently // Don't sleep when we are about to exit the loop & return ErrFailedPermanently
if i != maxAttempts-1 { if i != maxAttempts-1 {
time.Sleep(strategy.Duration(i)) time.Sleep(strategy.Duration(i))
} }
} }
return empty, &ErrFailedPermanently{ return &ErrFailedPermanently{
attempts: maxAttempts, attempts: maxAttempts,
LastErr: err, LastErr: err,
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment