package redis import ( "context" "time" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/logger" ) const ( baseWatchBackoffDelay = time.Millisecond * 500 maxDelay = time.Minute * 10 ) func retryWithBackoff(ctx context.Context, attempts int, fn func(ctx context.Context) error) error { backoffDelay := baseWatchBackoffDelay count := 0 for { err := fn(ctx) if err == nil { return nil } err = errors.WithStack(err) count++ if count >= attempts { return errors.Wrapf(err, "execution failed after %d attempts", attempts) } logger.Error(ctx, "error while executing func, retrying with backoff", logger.CapturedE(err), logger.F("backoffDelay", backoffDelay), logger.F("remainingAttempts", attempts-count)) time.Sleep(backoffDelay) backoffDelay *= 2 if backoffDelay > maxDelay { backoffDelay = maxDelay } } }