github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/libkb/backoff.go (about)

     1  package libkb
     2  
     3  // from here:
     4  // https://blog.gopheracademy.com/advent-2014/backoff/
     5  
     6  import (
     7  	"math/rand"
     8  	"time"
     9  )
    10  
    11  // BackoffPolicy implements a backoff policy, randomizing its delays
    12  // and saturating at the final value in Millis.
    13  type BackoffPolicy struct {
    14  	Millis []int
    15  }
    16  
    17  // BackoffDefault is a backoff policy ranging up to 5 seconds.
    18  var BackoffDefault = BackoffPolicy{
    19  	[]int{0, 10, 10, 100, 100, 500, 500, 3000, 3000, 5000},
    20  }
    21  
    22  // Duration returns the time duration of the n'th wait cycle in a
    23  // backoff policy. This is b.Millis[n], randomized to avoid thundering
    24  // herds.
    25  func (b BackoffPolicy) Duration(n int) time.Duration {
    26  	if n >= len(b.Millis) {
    27  		n = len(b.Millis) - 1
    28  	}
    29  
    30  	return time.Duration(jitter(b.Millis[n])) * time.Millisecond
    31  }
    32  
    33  // jitter returns a random integer uniformly distributed in the range
    34  // [0.5 * millis .. 1.5 * millis]
    35  func jitter(millis int) int {
    36  	if millis == 0 {
    37  		return 0
    38  	}
    39  
    40  	return millis/2 + rand.Intn(millis)
    41  }