backoff.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gensupport
  5. import (
  6. "math/rand"
  7. "time"
  8. )
  9. type BackoffStrategy interface {
  10. // Pause returns the duration of the next pause and true if the operation should be
  11. // retried, or false if no further retries should be attempted.
  12. Pause() (time.Duration, bool)
  13. // Reset restores the strategy to its initial state.
  14. Reset()
  15. }
  16. // ExponentialBackoff performs exponential backoff as per https://en.wikipedia.org/wiki/Exponential_backoff.
  17. // The initial pause time is given by Base.
  18. // Once the total pause time exceeds Max, Pause will indicate no further retries.
  19. type ExponentialBackoff struct {
  20. Base time.Duration
  21. Max time.Duration
  22. total time.Duration
  23. n uint
  24. }
  25. func (eb *ExponentialBackoff) Pause() (time.Duration, bool) {
  26. if eb.total > eb.Max {
  27. return 0, false
  28. }
  29. // The next pause is selected from randomly from [0, 2^n * Base).
  30. d := time.Duration(rand.Int63n((1 << eb.n) * int64(eb.Base)))
  31. eb.total += d
  32. eb.n++
  33. return d, true
  34. }
  35. func (eb *ExponentialBackoff) Reset() {
  36. eb.n = 0
  37. eb.total = 0
  38. }