github.com/mailgun/holster/v4@v4.20.0/etcdutil/backoff.go (about)

     1  package etcdutil
     2  
     3  import (
     4  	"math"
     5  	"time"
     6  )
     7  
     8  type backOffCounter struct {
     9  	min, max time.Duration
    10  	factor   float64
    11  	attempt  int
    12  }
    13  
    14  func newBackOffCounter(min, max time.Duration, factor float64) *backOffCounter {
    15  	return &backOffCounter{
    16  		factor: factor,
    17  		min:    min,
    18  		max:    max,
    19  	}
    20  }
    21  
    22  // Next returns the next back off duration based on the number of
    23  // times Next() was called. Each call to next returns the next factor
    24  // of back off. Call Reset() to reset the back off attempts to zero.
    25  func (b *backOffCounter) Next() time.Duration {
    26  	d := b.BackOff(b.attempt)
    27  	b.attempt++
    28  	return d
    29  }
    30  
    31  // Reset sets the back off attempt counter to zero
    32  func (b *backOffCounter) Reset() {
    33  	b.attempt = 0
    34  }
    35  
    36  // BackOff calculates the back depending on the attempts provided
    37  func (b *backOffCounter) BackOff(attempt int) time.Duration {
    38  	d := time.Duration(float64(b.min) * math.Pow(b.factor, float64(attempt)))
    39  	if d > b.max {
    40  		return b.max
    41  	}
    42  	if d < b.min {
    43  		return b.min
    44  	}
    45  	return d
    46  }