retry.go 681 B

123456789101112131415161718192021222324252627282930313233343536373839
  1. package util
  2. import (
  3. "math/rand"
  4. "time"
  5. )
  6. func init() {
  7. rand.Seed(time.Now().UnixNano())
  8. }
  9. func Retry(attempts int, sleep time.Duration, f func() error) error {
  10. if err := f(); err != nil {
  11. if s, ok := err.(retryStop); ok {
  12. // Return the original error for later checking
  13. return s.error
  14. }
  15. if attempts--; attempts > 0 {
  16. // Add some randomness to prevent creating a Thundering Herd
  17. jitter := time.Duration(rand.Int63n(int64(sleep)))
  18. sleep = sleep + jitter/2
  19. time.Sleep(sleep)
  20. return Retry(attempts, 2*sleep, f)
  21. }
  22. return err
  23. }
  24. return nil
  25. }
  26. type retryStop struct {
  27. error
  28. }
  29. func RetryStopErr(err error) retryStop {
  30. return retryStop{err}
  31. }