diff options
Diffstat (limited to 'vendor/github.com/jpillora/backoff')
-rw-r--r-- | vendor/github.com/jpillora/backoff/LICENSE | 21 | ||||
-rw-r--r-- | vendor/github.com/jpillora/backoff/backoff.go | 83 |
2 files changed, 72 insertions, 32 deletions
diff --git a/vendor/github.com/jpillora/backoff/LICENSE b/vendor/github.com/jpillora/backoff/LICENSE new file mode 100644 index 00000000..1cc70808 --- /dev/null +++ b/vendor/github.com/jpillora/backoff/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Jaime Pillora + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/jpillora/backoff/backoff.go b/vendor/github.com/jpillora/backoff/backoff.go index c8ea03a6..a50d0e95 100644 --- a/vendor/github.com/jpillora/backoff/backoff.go +++ b/vendor/github.com/jpillora/backoff/backoff.go @@ -1,3 +1,4 @@ +// Package backoff provides an exponential-backoff implementation. package backoff import ( @@ -6,64 +7,82 @@ import ( "time" ) -//Backoff is a time.Duration counter. It starts at Min. -//After every call to Duration() it is multiplied by Factor. -//It is capped at Max. It returns to Min on every call to Reset(). -//Used in conjunction with the time package. +// Backoff is a time.Duration counter, starting at Min. After every call to +// the Duration method the current timing is multiplied by Factor, but it +// never exceeds Max. // -// Backoff is not threadsafe, but the ForAttempt method can be -// used concurrently if non-zero values for Factor, Max, and Min -// are set on the Backoff shared among threads. +// Backoff is not generally concurrent-safe, but the ForAttempt method can +// be used concurrently. type Backoff struct { //Factor is the multiplying factor for each increment step - attempts, Factor float64 + attempt, Factor float64 //Jitter eases contention by randomizing backoff steps Jitter bool //Min and Max are the minimum and maximum values of the counter Min, Max time.Duration } -//Returns the current value of the counter and then -//multiplies it Factor +// Duration returns the duration for the current attempt before incrementing +// the attempt counter. See ForAttempt. func (b *Backoff) Duration() time.Duration { - d := b.ForAttempt(b.attempts) - b.attempts++ + d := b.ForAttempt(b.attempt) + b.attempt++ return d } +const maxInt64 = float64(math.MaxInt64 - 512) + // ForAttempt returns the duration for a specific attempt. This is useful if // you have a large number of independent Backoffs, but don't want use // unnecessary memory storing the Backoff parameters per Backoff. The first // attempt should be 0. // -// ForAttempt is threadsafe iff non-zero values for Factor, Max, and Min -// are set before any calls to ForAttempt are made. +// ForAttempt is concurrent-safe. func (b *Backoff) ForAttempt(attempt float64) time.Duration { - //Zero-values are nonsensical, so we use - //them to apply defaults - if b.Min == 0 { - b.Min = 100 * time.Millisecond + // Zero-values are nonsensical, so we use + // them to apply defaults + min := b.Min + if min <= 0 { + min = 100 * time.Millisecond + } + max := b.Max + if max <= 0 { + max = 10 * time.Second } - if b.Max == 0 { - b.Max = 10 * time.Second + if min >= max { + // short-circuit + return max } - if b.Factor == 0 { - b.Factor = 2 + factor := b.Factor + if factor <= 0 { + factor = 2 } //calculate this duration - dur := float64(b.Min) * math.Pow(b.Factor, attempt) - if b.Jitter == true { - dur = rand.Float64()*(dur-float64(b.Min)) + float64(b.Min) + minf := float64(min) + durf := minf * math.Pow(factor, attempt) + if b.Jitter { + durf = rand.Float64()*(durf-minf) + minf + } + //ensure float64 wont overflow int64 + if durf > maxInt64 { + return max } - //cap! - if dur > float64(b.Max) { - return b.Max + dur := time.Duration(durf) + //keep within bounds + if dur < min { + return min + } else if dur > max { + return max } - //return as a time.Duration - return time.Duration(dur) + return dur } -//Resets the current value of the counter back to Min +// Reset restarts the current attempt counter at zero. func (b *Backoff) Reset() { - b.attempts = 0 + b.attempt = 0 +} + +// Attempt returns the current attempt counter value. +func (b *Backoff) Attempt() float64 { + return b.attempt } |