Last active
March 6, 2020 18:18
-
-
Save tryggvigy/55b864394d8cff71f5cbb0de4aa90808 to your computer and use it in GitHub Desktop.
Promise retries with exponential backoff
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
// paste this in any JS REPL to see the execution! | |
// Note that the fakeAPI is simulated to be flaky so try executin this a few times | |
// to see both the success and failure case | |
(() => { | |
/** | |
* Wrap a promise API with a function that will attempt the promise over and over again | |
* with exponential backoff until it resolves or reaches the maximum number of retries. | |
* - First retry: 500 ms + <random> ms | |
* - Second retry: 1000 ms + <random> ms | |
* - Third retry: 2000 ms + <random> ms | |
* and so forth until maximum retries are met, or the promise resolves. | |
*/ | |
const withRetries = ({ attempt, maxRetries }) => async (...args) => { | |
const slotTime = 500; | |
let retryCount = 0; | |
do { | |
try { | |
console.log('Attempting...', Date.now()); | |
return await attempt(...args); | |
} catch (error) { | |
const isLastAttempt = retryCount === maxRetries; | |
if (isLastAttempt) return Promise.reject(error); | |
} | |
const randomTime = Math.floor(Math.random() * slotTime); | |
const delay = 2 ** retryCount * slotTime + randomTime; | |
// Wait for the exponentially increasing delay period before retrying again. | |
await new Promise(resolve => setTimeout(resolve, delay)); | |
} while (retryCount++ < maxRetries); | |
} | |
const fakeAPI = (...args) => Math.random() < 0.25 ? Promise.resolve(args) : Promise.reject(new Error('fakeAPI failure')) | |
const fakeAPIWithRetries = withRetries({ attempt: fakeAPI, maxRetries: 3 }); | |
fakeAPIWithRetries('arg1', 'arg2').then((result) => console.log(result)) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment