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 }