github.com/spi-ca/misc@v1.0.1/backoff/backoff.go (about) 1 package backoff 2 3 import ( 4 "math" 5 "time" 6 ) 7 8 // Algorithm defines a function that calculates a time.Duration based on 9 // the given retry attempt number. 10 type Algorithm func(attempt uint) time.Duration 11 12 // Incremental creates a Algorithm that increments the initial duration 13 // by the given increment for each attempt. 14 func Incremental(initial, increment time.Duration) Algorithm { 15 return func(attempt uint) time.Duration { 16 return initial + (increment * time.Duration(attempt)) 17 } 18 } 19 20 // Linear creates a Algorithm that linearly multiplies the factor 21 // duration by the attempt number for each attempt. 22 func Linear(factor time.Duration) Algorithm { 23 return func(attempt uint) time.Duration { 24 return factor * time.Duration(attempt) 25 } 26 } 27 28 // Exponential creates a Algorithm that multiplies the factor duration by 29 // an exponentially increasing factor for each attempt, where the factor is 30 // calculated as the given base raised to the attempt number. 31 func Exponential(factor time.Duration, base float64) Algorithm { 32 return func(attempt uint) time.Duration { 33 return factor * time.Duration(math.Pow(base, float64(attempt))) 34 } 35 } 36 37 // BinaryExponential creates a Algorithm that multiplies the factor 38 // duration by an exponentially increasing factor for each attempt, where the 39 // factor is calculated as `2` raised to the attempt number (2^attempt). 40 func BinaryExponential(factor time.Duration) Algorithm { 41 return Exponential(factor, 2) 42 } 43 44 // Fibonacci creates a Algorithm that multiplies the factor duration by 45 // an increasing factor for each attempt, where the factor is the Nth number in 46 // the Fibonacci sequence. 47 func Fibonacci(factor time.Duration) Algorithm { 48 return func(attempt uint) time.Duration { 49 return factor * time.Duration(fibonacciNumber(attempt)) 50 } 51 } 52 53 // fibonacciNumber calculates the Fibonacci sequence number for the given 54 // sequence position. 55 func fibonacciNumber(n uint) uint { 56 if 0 == n { 57 return 0 58 } else if 1 == n { 59 return 1 60 } else { 61 return fibonacciNumber(n-1) + fibonacciNumber(n-2) 62 } 63 }