I was trying to write code for reconnecting to a database with a timeout using a Promise API.
What I ended up doing in the end was wrapping the promise to connect to the DB in a promise, but I'm not sure if that's the best way to do things. I thought there might be a way to use the original promise from trying to connect to the db, but I couldn't figure it out.
function connect(resolve) {
console.log('Connecting to db...');
MongoClient.connect(url, { promiseLibrary: Promise })
.then((db) => resolve(db))
.catch((err) => {
console.log('db connection failed!:\n', err);
if (retry++ < 3) {
console.log('Trying again...');
setTimeout(() => connect(resolve), 5000);
} else {
console.log('Retry limit reached!');
}
});
}
module.exports = new Promise(connect);
I think it would be possible without the setTimeout
block, but I couldn't work around it.
Here's a slightly more general solution (tests for non-positive):
function withRetry(asyncAction, retries) {
if (retries <= 0) {
// Promise.resolve to convert sync throws into rejections.
return Promise.resolve().then(asyncAction);
}
return Promise.resolve()
.then(asyncAction)
.catch(() => withRetry(asyncAction, retries - 1));
}
This function will take a function that returns a promise, and a number of retries, and retry the function as many times as retries
, if the Promise rejects.
If it resolves, the retry chains stops.
In your case:
let connectionPromise = withRetry(connect, 3); // connect with 3 retries if fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With