42 lines
704 B
Go
42 lines
704 B
Go
|
|
package ingestion
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
type Retrier struct {
|
||
|
|
MaxRetries int
|
||
|
|
BaseDelay time.Duration
|
||
|
|
}
|
||
|
|
|
||
|
|
func NewRetrier(maxRetries int, baseDelay time.Duration) *Retrier {
|
||
|
|
return &Retrier{
|
||
|
|
MaxRetries: maxRetries,
|
||
|
|
BaseDelay: baseDelay,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r *Retrier) Do(ctx context.Context, fn func() (int64, error)) (int64, error) {
|
||
|
|
var lastErr error
|
||
|
|
|
||
|
|
for attempt := 0; attempt <= r.MaxRetries; attempt++ {
|
||
|
|
if attempt > 0 {
|
||
|
|
delay := r.BaseDelay * time.Duration(1<<uint(attempt-1))
|
||
|
|
select {
|
||
|
|
case <-ctx.Done():
|
||
|
|
return 0, ctx.Err()
|
||
|
|
case <-time.After(delay):
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
result, err := fn()
|
||
|
|
if err == nil {
|
||
|
|
return result, nil
|
||
|
|
}
|
||
|
|
lastErr = err
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0, lastErr
|
||
|
|
}
|