Last active
August 8, 2022 00:10
-
-
Save marselester/b58b11337a09a0defb6466793bef8da0 to your computer and use it in GitHub Desktop.
Exponential decorrelated jitter backoff from Polly project based on https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/, see an example https://play.golang.org/p/sHOTAI6wGht.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math" | |
"math/rand" | |
"time" | |
) | |
func main() { | |
// Initialize the default source of uniformly-distributed pseudo-random numbers. | |
rand.Seed(time.Now().UnixNano()) | |
// Make 6 retries with exponential backoff and 1 hour of max wait time between attempts. | |
// The first delay of 200 seconds is a multiplier that increases the wait intervals. | |
const ( | |
maxRetries = 6 | |
maxSeconds = 3600. | |
firstDelaySeconds = 200. | |
) | |
retries := backoff(maxRetries, maxSeconds, firstDelaySeconds) | |
fmt.Println(retries) | |
} | |
const ( | |
// pFactor is a factor used within the formula to help smooth the first calculated delay. | |
pFactor = 4.0 | |
// rpScalingFactor is a factor used to scale the median values of the retry times | |
// generated by the formula to be near whole seconds, to aid user comprehension. | |
// This factor allows the median values to fall approximately at 1, 2, 4, ... seconds, | |
// instead of 1.4, 2.8, 5.6, 11.2. | |
rpScalingFactor = 1 / 1.4 | |
) | |
// backoff is the exponential "Decorrelated Jitter" backoff from Polly project | |
// based on https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/. | |
// Read more https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry#new-jitter-recommendation and | |
// https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry/blob/master/src/Polly.Contrib.WaitAndRetry/Backoff.DecorrelatedJitterV2.cs. | |
func backoff(maxRetries int, maxSeconds, firstDelaySeconds float64) []float64 { | |
retries := make([]float64, maxRetries) | |
var prev float64 | |
for i := 0; i < maxRetries; i++ { | |
t := float64(i) + rand.Float64() | |
next := math.Pow(2, t) * math.Tanh(math.Sqrt(pFactor*t)) | |
retries[i] = math.Min( | |
(next-prev)*rpScalingFactor*firstDelaySeconds, | |
maxSeconds, | |
) | |
prev = next | |
} | |
return retries | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is a Go package that does the same thing https://github.com/marselester/backoff.