Skip to content

Commit

Permalink
Database: Don't sleep 10ms before every request (grafana#64832)
Browse files Browse the repository at this point in the history
Previously every DB operation would wait 10ms before even trying.
Now we try first, and defer creating the ticker until we need it.
  • Loading branch information
bboreham authored Mar 27, 2023
1 parent 31d6416 commit f4a5f91
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 22 deletions.
36 changes: 17 additions & 19 deletions pkg/util/retryer/retryer.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package retryer

import (
"errors"
"time"
)

type RetrySignal = int

const (
FuncSuccess RetrySignal = iota
FuncFailure
FuncFailure RetrySignal = iota
FuncComplete
FuncError
)
Expand All @@ -17,35 +17,33 @@ const (
// `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()
var ticker *time.Ticker

retries := 0
for range ticker.C {
for {
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:
if response == FuncComplete {
return nil
}

retries++
if retries >= maxRetries {
return nil
return errors.New("max retries exceeded")
}
}

return nil
if ticker == nil {
ticker = time.NewTicker(currentDelay)
defer ticker.Stop()
} else {
currentDelay = minDuration(currentDelay*2, maxDelay)
ticker.Reset(currentDelay)
}

<-ticker.C
}
}

func minDuration(a time.Duration, b time.Duration) time.Duration {
Expand Down
4 changes: 1 addition & 3 deletions pkg/util/retryer/retryer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ func TestMaxRetries(t *testing.T) {
retryVal++
return FuncFailure, nil
}, 8, 100*time.Millisecond, 100*time.Millisecond)
if err != nil {
assert.FailNow(t, "Error while retrying function")
}
assert.Error(t, err) // Exceeding max-retries is an error.

assert.Equal(t, 8, retryVal)
}

0 comments on commit f4a5f91

Please sign in to comment.