You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

52 lines
1.5 KiB

  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. // BackoffStrategy defines the set of functions that a backoff-er must
  10. // implement.
  11. type BackoffStrategy interface {
  12. // Pause returns the duration of the next pause and true if the operation should be
  13. // retried, or false if no further retries should be attempted.
  14. Pause() (time.Duration, bool)
  15. // Reset restores the strategy to its initial state.
  16. Reset()
  17. }
  18. // ExponentialBackoff performs exponential backoff as per https://en.wikipedia.org/wiki/Exponential_backoff.
  19. // The initial pause time is given by Base.
  20. // Once the total pause time exceeds Max, Pause will indicate no further retries.
  21. type ExponentialBackoff struct {
  22. Base time.Duration
  23. Max time.Duration
  24. total time.Duration
  25. n uint
  26. }
  27. // Pause returns the amount of time the caller should wait.
  28. func (eb *ExponentialBackoff) Pause() (time.Duration, bool) {
  29. if eb.total > eb.Max {
  30. return 0, false
  31. }
  32. // The next pause is selected from randomly from [0, 2^n * Base).
  33. d := time.Duration(rand.Int63n((1 << eb.n) * int64(eb.Base)))
  34. eb.total += d
  35. eb.n++
  36. return d, true
  37. }
  38. // Reset resets the backoff strategy such that the next Pause call will begin
  39. // counting from the start. It is not safe to call concurrently with Pause.
  40. func (eb *ExponentialBackoff) Reset() {
  41. eb.n = 0
  42. eb.total = 0
  43. }