retry.go 890 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. package retry
  2. import (
  3. "errors"
  4. "time"
  5. )
  6. var (
  7. ErrRetryFailed = errors.New("All retry attempts failed.")
  8. )
  9. // Strategy is a way to retry on a specific function.
  10. type Strategy interface {
  11. // On performs a retry on a specific function, until it doesn't return any error.
  12. On(func() error) error
  13. }
  14. type retryer struct {
  15. NextDelay func(int) int
  16. }
  17. // On implements Strategy.On.
  18. func (r *retryer) On(method func() error) error {
  19. attempt := 0
  20. for {
  21. err := method()
  22. if err == nil {
  23. return nil
  24. }
  25. delay := r.NextDelay(attempt)
  26. if delay < 0 {
  27. return ErrRetryFailed
  28. }
  29. <-time.After(time.Duration(delay) * time.Millisecond)
  30. attempt++
  31. }
  32. }
  33. // Timed returns a retry strategy with fixed interval.
  34. func Timed(attempts int, delay int) Strategy {
  35. return &retryer{
  36. NextDelay: func(attempt int) int {
  37. if attempt >= attempts {
  38. return -1
  39. }
  40. return delay
  41. },
  42. }
  43. }