summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/olivere/elastic/backoff.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/olivere/elastic/backoff.go')
-rw-r--r--vendor/github.com/olivere/elastic/backoff.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/vendor/github.com/olivere/elastic/backoff.go b/vendor/github.com/olivere/elastic/backoff.go
new file mode 100644
index 000000000..736959f6d
--- /dev/null
+++ b/vendor/github.com/olivere/elastic/backoff.go
@@ -0,0 +1,148 @@
+// Copyright 2012-present Oliver Eilhard. All rights reserved.
+// Use of this source code is governed by a MIT-license.
+// See http://olivere.mit-license.org/license.txt for details.
+
+package elastic
+
+import (
+ "math"
+ "math/rand"
+ "sync"
+ "time"
+)
+
+// BackoffFunc specifies the signature of a function that returns the
+// time to wait before the next call to a resource. To stop retrying
+// return false in the 2nd return value.
+type BackoffFunc func(retry int) (time.Duration, bool)
+
+// Backoff allows callers to implement their own Backoff strategy.
+type Backoff interface {
+ // Next implements a BackoffFunc.
+ Next(retry int) (time.Duration, bool)
+}
+
+// -- ZeroBackoff --
+
+// ZeroBackoff is a fixed backoff policy whose backoff time is always zero,
+// meaning that the operation is retried immediately without waiting,
+// indefinitely.
+type ZeroBackoff struct{}
+
+// Next implements BackoffFunc for ZeroBackoff.
+func (b ZeroBackoff) Next(retry int) (time.Duration, bool) {
+ return 0, true
+}
+
+// -- StopBackoff --
+
+// StopBackoff is a fixed backoff policy that always returns false for
+// Next(), meaning that the operation should never be retried.
+type StopBackoff struct{}
+
+// Next implements BackoffFunc for StopBackoff.
+func (b StopBackoff) Next(retry int) (time.Duration, bool) {
+ return 0, false
+}
+
+// -- ConstantBackoff --
+
+// ConstantBackoff is a backoff policy that always returns the same delay.
+type ConstantBackoff struct {
+ interval time.Duration
+}
+
+// NewConstantBackoff returns a new ConstantBackoff.
+func NewConstantBackoff(interval time.Duration) *ConstantBackoff {
+ return &ConstantBackoff{interval: interval}
+}
+
+// Next implements BackoffFunc for ConstantBackoff.
+func (b *ConstantBackoff) Next(retry int) (time.Duration, bool) {
+ return b.interval, true
+}
+
+// -- Exponential --
+
+// ExponentialBackoff implements the simple exponential backoff described by
+// Douglas Thain at http://dthain.blogspot.de/2009/02/exponential-backoff-in-distributed.html.
+type ExponentialBackoff struct {
+ t float64 // initial timeout (in msec)
+ f float64 // exponential factor (e.g. 2)
+ m float64 // maximum timeout (in msec)
+}
+
+// NewExponentialBackoff returns a ExponentialBackoff backoff policy.
+// Use initialTimeout to set the first/minimal interval
+// and maxTimeout to set the maximum wait interval.
+func NewExponentialBackoff(initialTimeout, maxTimeout time.Duration) *ExponentialBackoff {
+ return &ExponentialBackoff{
+ t: float64(int64(initialTimeout / time.Millisecond)),
+ f: 2.0,
+ m: float64(int64(maxTimeout / time.Millisecond)),
+ }
+}
+
+// Next implements BackoffFunc for ExponentialBackoff.
+func (b *ExponentialBackoff) Next(retry int) (time.Duration, bool) {
+ r := 1.0 + rand.Float64() // random number in [1..2]
+ m := math.Min(r*b.t*math.Pow(b.f, float64(retry)), b.m)
+ if m >= b.m {
+ return 0, false
+ }
+ d := time.Duration(int64(m)) * time.Millisecond
+ return d, true
+}
+
+// -- Simple Backoff --
+
+// SimpleBackoff takes a list of fixed values for backoff intervals.
+// Each call to Next returns the next value from that fixed list.
+// After each value is returned, subsequent calls to Next will only return
+// the last element. The values are optionally "jittered" (off by default).
+type SimpleBackoff struct {
+ sync.Mutex
+ ticks []int
+ jitter bool
+}
+
+// NewSimpleBackoff creates a SimpleBackoff algorithm with the specified
+// list of fixed intervals in milliseconds.
+func NewSimpleBackoff(ticks ...int) *SimpleBackoff {
+ return &SimpleBackoff{
+ ticks: ticks,
+ jitter: false,
+ }
+}
+
+// Jitter enables or disables jittering values.
+func (b *SimpleBackoff) Jitter(flag bool) *SimpleBackoff {
+ b.Lock()
+ b.jitter = flag
+ b.Unlock()
+ return b
+}
+
+// jitter randomizes the interval to return a value of [0.5*millis .. 1.5*millis].
+func jitter(millis int) int {
+ if millis <= 0 {
+ return 0
+ }
+ return millis/2 + rand.Intn(millis)
+}
+
+// Next implements BackoffFunc for SimpleBackoff.
+func (b *SimpleBackoff) Next(retry int) (time.Duration, bool) {
+ b.Lock()
+ defer b.Unlock()
+
+ if retry >= len(b.ticks) {
+ return 0, false
+ }
+
+ ms := b.ticks[retry]
+ if b.jitter {
+ ms = jitter(ms)
+ }
+ return time.Duration(ms) * time.Millisecond, true
+}