The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/util/retryer/retryer.go

56 lines
1.1 KiB

package retryer
import (
"time"
)
type RetrySignal = int
const (
FuncSuccess RetrySignal = iota
FuncFailure
FuncComplete
FuncError
)
// Retry retries the provided function using exponential backoff, starting with `minDelay` between attempts, and increasing to
// `maxDelay` after each failure. Stops when the provided function returns `FuncComplete`, or `maxRetries` is reached.
func Retry(body func() (RetrySignal, error), maxRetries int, minDelay time.Duration, maxDelay time.Duration) error {
currentDelay := minDelay
ticker := time.NewTicker(currentDelay)
defer ticker.Stop()
retries := 0
for range ticker.C {
response, err := body()
if err != nil {
return err
}
switch response {
case FuncSuccess:
currentDelay = minDelay
ticker.Reset(currentDelay)
retries = 0
case FuncFailure:
currentDelay = minDuration(currentDelay*2, maxDelay)
ticker.Reset(currentDelay)
retries++
case FuncComplete:
return nil
}
if retries >= maxRetries {
return nil
}
}
return nil
}
func minDuration(a time.Duration, b time.Duration) time.Duration {
if a < b {
return a
}
return b
}