golang-queue/queue

Support Retry with exponential backoff time duration.

appleboy opened this issue · 2 comments

Support Retry with exponential backoff time duration.

We can implement it using cenkalti/backoff as follows:

package main

import (
	"context"
	"errors"
	"time"

	"github.com/cenkalti/backoff/v4"
)

func doSomething() error {
	return errors.New("failed")
}

func main() {
	ctx := context.Background()

	retryCount := 10

	bo := backoff.NewExponentialBackOff()
	bo.InitialInterval = 1 * time.Second
	bo.MaxInterval = 10 * time.Second
	bo.MaxElapsedTime = 0
	bo.Reset()

loop:
	for {
		err := doSomething()

		// check error and retry count
		if err == nil || retryCount == 0 {
			break
		}
		retryCount--

		select {
		case <-time.After(bo.NextBackOff()):
		case <-ctx.Done(): // timeout reached
			err = ctx.Err()
			break loop
		}
	}
}

(or using backoff.Retry() combined with backoff.WithMaxRetries() and backoff.WithContext())

We may need to remove RetryDelay from messages and include InitialDelay and MaxDelay (bo.InitialInterval and bo.MaxInterval , respectively). If both values are the same, then use a constant backoff instead.

If you think it's ok, I can submit a PR.

@benhid I implemented the first version using the lightweight package https://github.com/jpillora/backoff

see the detailed information #94