Skip to content
This repository has been archived by the owner on Apr 15, 2024. It is now read-only.

Commit

Permalink
feat: implement simple exponential backoff for retries (#302)
Browse files Browse the repository at this point in the history
  • Loading branch information
rach-id authored Apr 24, 2023
1 parent bdfe030 commit 59db7a2
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
2 changes: 1 addition & 1 deletion cmd/qgb/common/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ func InitBase(

// creating the p2p querier
p2pQuerier := p2p.NewQuerier(dht, logger)
retrier := helpers.NewRetrier(logger, 5, 15*time.Second)
retrier := helpers.NewRetrier(logger, 6, time.Minute)

return tmQuerier, appQuerier, p2pQuerier, retrier, s.EVMKeyStore, &acc, stopFuncs, nil
}
22 changes: 14 additions & 8 deletions helpers/retrier.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,31 @@ import (
type Retrier struct {
logger tmlog.Logger
retriesNumber int
delay time.Duration
baseDelay time.Duration
}

// DefaultRetrierDelay default retrier delay
// DefaultRetrierDelay default retrier baseDelay
const DefaultRetrierDelay = 10 * time.Second

func NewRetrier(logger tmlog.Logger, retriesNumber int, delay time.Duration) *Retrier {
func NewRetrier(logger tmlog.Logger, retriesNumber int, baseDelay time.Duration) *Retrier {
return &Retrier{
logger: logger,
retriesNumber: retriesNumber,
delay: delay,
baseDelay: baseDelay,
}
}

// Retry retries the `retryMethod` for `r.retriesNumber` times, separated by a delay equal to `r.delay`.
// Retry retries the `retryMethod` for `r.retriesNumber` times, separated by an exponential delay
// calculated using the `NextTick(retryCount)` method.
// Returns the final execution error if all retries failed.
func (r Retrier) Retry(ctx context.Context, retryMethod func() error) error {
var err error
ticker := time.NewTicker(r.delay)
for i := 0; i < r.retriesNumber; i++ {
// We can implement some exponential backoff in here
nextTick := time.NewTimer(r.NextTick(i))
select {
case <-ctx.Done():
return ctx.Err()
case <-ticker.C:
case <-nextTick.C:
r.logger.Info("retrying", "retry_number", i, "retries_left", r.retriesNumber-i)
err = retryMethod()
if err == nil {
Expand All @@ -55,3 +55,9 @@ func (r Retrier) RetryThenFail(ctx context.Context, retryMethod func() error) {
panic(err)
}
}

// NextTick calculates the next exponential tick based on the provided retry count
// and the initialized base delay.
func (r Retrier) NextTick(retryCount int) time.Duration {
return 1 << retryCount * r.baseDelay
}

0 comments on commit 59db7a2

Please sign in to comment.