• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5package gensupport
6
7import (
8	"math/rand"
9	"time"
10)
11
12type BackoffStrategy interface {
13	// Pause returns the duration of the next pause and true if the operation should be
14	// retried, or false if no further retries should be attempted.
15	Pause() (time.Duration, bool)
16
17	// Reset restores the strategy to its initial state.
18	Reset()
19}
20
21// ExponentialBackoff performs exponential backoff as per https://en.wikipedia.org/wiki/Exponential_backoff.
22// The initial pause time is given by Base.
23// Once the total pause time exceeds Max, Pause will indicate no further retries.
24type ExponentialBackoff struct {
25	Base  time.Duration
26	Max   time.Duration
27	total time.Duration
28	n     uint
29}
30
31func (eb *ExponentialBackoff) Pause() (time.Duration, bool) {
32	if eb.total > eb.Max {
33		return 0, false
34	}
35
36	// The next pause is selected from randomly from [0, 2^n * Base).
37	d := time.Duration(rand.Int63n((1 << eb.n) * int64(eb.Base)))
38	eb.total += d
39	eb.n++
40	return d, true
41}
42
43func (eb *ExponentialBackoff) Reset() {
44	eb.n = 0
45	eb.total = 0
46}
47