backoff.go 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // package backoff implemenets policies for waiting differente ammounts of times when retrying something.
  2. //
  3. // Taken from Peter Teichman's post on http://blog.gopheracademy.com/advent-2014/backoff/
  4. package backoff
  5. import (
  6. "math/rand"
  7. "time"
  8. )
  9. type Backoff interface {
  10. Duration(n int) time.Duration
  11. }
  12. var (
  13. // Default is a backoff policy ranging up to 5 seconds.
  14. Default = IncreasePolicy{
  15. []int{0, 10, 10, 100, 100, 500, 500, 3000, 3000, 5000},
  16. }
  17. Random = RandomPolicy{10 * time.Second}
  18. )
  19. // IncreasePolicy implements a backoff policy, randomizing its delays
  20. // and saturating at the final value in Millis.
  21. type IncreasePolicy struct {
  22. Millis []int
  23. }
  24. // Duration returns the time duration of the n'th wait cycle in a
  25. // backoff policy. This is b.Millis[n], randomized to avoid thundering
  26. // herds.
  27. func (b IncreasePolicy) Duration(n int) time.Duration {
  28. if n >= len(b.Millis) {
  29. n = len(b.Millis) - 1
  30. }
  31. return time.Duration(jitter(b.Millis[n])) * time.Millisecond
  32. }
  33. // jitter returns a random integer uniformly distributed in the range
  34. // [0.5 * millis .. 1.5 * millis]
  35. func jitter(millis int) int {
  36. if millis == 0 {
  37. return 0
  38. }
  39. return millis/2 + rand.Intn(millis)
  40. }
  41. type RandomPolicy struct {
  42. Max time.Duration
  43. }
  44. func (b RandomPolicy) Duration(n int) time.Duration {
  45. return time.Duration(rand.Int63() % int64(b.Max))
  46. }