github.com/outbrain/consul@v1.4.5/lib/cluster.go (about)

     1  package lib
     2  
     3  import (
     4  	"math/rand"
     5  	"time"
     6  )
     7  
     8  const (
     9  	// minRate is the minimum rate at which we allow an action to be performed
    10  	// across the whole cluster. The value is once a day: 1 / (1 * time.Day)
    11  	minRate = 1.0 / 86400
    12  )
    13  
    14  // DurationMinusBuffer returns a duration, minus a buffer and jitter
    15  // subtracted from the duration.  This function is used primarily for
    16  // servicing Consul TTL Checks in advance of the TTL.
    17  func DurationMinusBuffer(intv time.Duration, buffer time.Duration, jitter int64) time.Duration {
    18  	d := intv - buffer
    19  	if jitter == 0 {
    20  		d -= RandomStagger(d)
    21  	} else {
    22  		d -= RandomStagger(time.Duration(int64(d) / jitter))
    23  	}
    24  	return d
    25  }
    26  
    27  // DurationMinusBufferDomain returns the domain of valid durations from a
    28  // call to DurationMinusBuffer.  This function is used to check user
    29  // specified input values to DurationMinusBuffer.
    30  func DurationMinusBufferDomain(intv time.Duration, buffer time.Duration, jitter int64) (min time.Duration, max time.Duration) {
    31  	max = intv - buffer
    32  	if jitter == 0 {
    33  		min = max
    34  	} else {
    35  		min = max - time.Duration(int64(max)/jitter)
    36  	}
    37  	return min, max
    38  }
    39  
    40  // RandomStagger returns an interval between 0 and the duration
    41  func RandomStagger(intv time.Duration) time.Duration {
    42  	if intv == 0 {
    43  		return 0
    44  	}
    45  	return time.Duration(uint64(rand.Int63()) % uint64(intv))
    46  }
    47  
    48  // RateScaledInterval is used to choose an interval to perform an action in
    49  // order to target an aggregate number of actions per second across the whole
    50  // cluster.
    51  func RateScaledInterval(rate float64, min time.Duration, n int) time.Duration {
    52  	if rate <= minRate {
    53  		return min
    54  	}
    55  	interval := time.Duration(float64(time.Second) * float64(n) / rate)
    56  	if interval < min {
    57  		return min
    58  	}
    59  
    60  	return interval
    61  }