Last active
May 3, 2020 00:44
-
-
Save franklinharvey/a8a09fa7dfb1f53edda2cc764cb8b865 to your computer and use it in GitHub Desktop.
Full Jitter Exponential Backoff Algorithm
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
const BASE_TIMEOUT = 5 // in milliseconds, you can change this | |
const getTimeout = (attempt: number): number => { | |
const backoff = BASE_TIMEOUT * Math.pow(2, attempt) // exp. increases the timeout per attempt | |
const backoff_or_cap = Math.min(1000, backoff) // cap the timeout at 1 sec. | |
const ret = sample([0, backoff_or_cap]) // randomly choose between 0 and the backoff, this is the "jitter" part | |
return ret | |
} | |
// randomly choose from an array, a replacement of lodash's sample method | |
const sample = (arr: number[]) => { | |
const len = arr == null ? 0 : arr.length | |
return len ? arr[Math.floor(Math.random() * len)] : undefined | |
} | |
// here's an example of how it's used with DynamoDB, but this principle applies for any case where you need to batch operations but some number of those operations may conflict and need to be retried | |
class ExampleDynamoDBClass { | |
db: DynamoDB | |
MAX_ATTEMPTS = 3 | |
public onDBWrite = (input: DynamoDB.PutItemInput, attempt: number = 1): Promise<void> => { | |
return new Promise((resolve, reject) => { | |
this.db.putItem(input, (err, _) => { | |
if (err) { | |
if (attempt <= this.MAX_ATTEMPTS) { | |
const timeout = getTimeout(attempt) | |
console.log(`[putItem] write failed(${err}), retrying(attempt ${attempt}, backoff: ${timeout}ms)`) | |
setTimeout(() => { | |
resolve(this.onDBWrite(input, attempt + 1)) | |
}, timeout) | |
} else { | |
reject(`[putItem] ${err}: ${JSON.stringify(input)}`) | |
} | |
} | |
else resolve() | |
}) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment