2022-08-17 18:22:31 +00:00
|
|
|
package retry
|
|
|
|
|
|
|
|
import (
|
2022-09-28 15:07:05 +00:00
|
|
|
"context"
|
2022-08-17 18:22:31 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
logging "github.com/ipfs/go-log/v2"
|
2022-09-22 16:50:05 +00:00
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/api"
|
2022-08-17 18:22:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var log = logging.Logger("retry")
|
|
|
|
|
2022-09-28 15:07:05 +00:00
|
|
|
func Retry[T any](ctx context.Context, attempts int, initialBackoff time.Duration, errorTypes []error, f func() (T, error)) (result T, err error) {
|
2022-08-17 18:22:31 +00:00
|
|
|
for i := 0; i < attempts; i++ {
|
|
|
|
if i > 0 {
|
|
|
|
log.Info("Retrying after error:", err)
|
2022-08-22 21:32:43 +00:00
|
|
|
time.Sleep(initialBackoff)
|
|
|
|
initialBackoff *= 2
|
2022-08-17 18:22:31 +00:00
|
|
|
}
|
|
|
|
result, err = f()
|
2022-09-22 16:50:05 +00:00
|
|
|
if err == nil || !api.ErrorIsIn(err, errorTypes) {
|
2022-08-19 15:33:37 +00:00
|
|
|
return result, err
|
2022-08-17 18:22:31 +00:00
|
|
|
}
|
2022-09-28 15:07:05 +00:00
|
|
|
if ctx.Err() != nil {
|
|
|
|
return result, ctx.Err()
|
|
|
|
}
|
2022-08-17 18:22:31 +00:00
|
|
|
}
|
|
|
|
log.Errorf("Failed after %d attempts, last error: %s", attempts, err)
|
|
|
|
return result, err
|
|
|
|
}
|