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