UPDATE: I am using the 2.1 version on the driver, against 3.2
I have a node application that uses MongoDB. The problem I have is that if the MongoDB server goes down for any reason, the application doesn't reconnect. To get this right, I based my tests on the code in this official tutorial.
var MongoClient = require('mongodb').MongoClient , f = require('util').format; MongoClient.connect('mongodb://localhost:27017/test', // Optional: uncomment if necessary // { db: { bufferMaxEntries: 3 } }, function(err, db) { var col = db.collection('t'); setInterval(function() { col.insert({a:1}, function(err, r) { console.log("insert") console.log(err) col.findOne({}, function(err, doc) { console.log("findOne") console.log(err) }); }) }, 1000) });
The idea is to run this script, and then stop mongod, and then restart it. So, here we go:
Stopping MongoDb for 10 seconds does the desired result: it will stop running the queries for those 10 seconds, and then will run all of them once the server is back ip
After exactly 30 seconds, I start getting:
{ [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' } insert { [MongoError: topology was destroyed] name: 'MongoError', message: 'topology was destroyed' }
The trouble is that from this on, when I restart mongod, the connection is not re-establised.
Does this problem have a solution? If so, do you know what it is? Once my app starts puking "topology was destroyed", the only way to get everything to work again is by restarting the whole app...
It is best practice to keep the connection open between your application and the database server.
If you have created a user and are having trouble authenticating, try the following: Check that you are using the correct username and password for your database user, and that you are connecting to the correct database deployment. Check that you are specifying the correct authSource database in your connection string.
Most MongoDB drivers support a parameter that sets the max number of connections (pool size) available to your application. The connection pool size can be thought of as the max number of concurrent requests that your driver can service.
There are 2 connection options that control how mongo nodejs driver reconnects after connection fails
reference on mongo driver docs
Which means that mongo will keep trying to connect 30 times by default and wait 1 second before every retry. Which is why you start seeing errors after 30 seconds.
You should tweak these 2 parameters based on you needs like this sample.
var MongoClient = require('mongodb').MongoClient, f = require('util').format; MongoClient.connect('mongodb://localhost:27017/test', { // retry to connect for 60 times reconnectTries: 60, // wait 1 second before retrying reconnectInterval: 1000 }, function(err, db) { var col = db.collection('t'); setInterval(function() { col.insert({ a: 1 }, function(err, r) { console.log("insert") console.log(err) col.findOne({}, function(err, doc) { console.log("findOne") console.log(err) }); }) }, 1000) });
This will try 60 times instead of the default 30, which means that you'll start seeing errors after 60 seconds when it stops trying to reconnect.
Sidenote: if you want to prevent the app/request from waiting until the expiration of the reconnection period you have to pass the option bufferMaxEntries: 0
. The price for this is that requests are also aborted during short network interruptions.
"mongodb": "3.1.3"
To fine-tune the reconnect configuration for pre-established connections, you can modify the reconnectTries
/reconnectInterval
options (default values and further documentation here).
For the initial connection, the mongo client does not reconnect if it encounters an error (see below). I believe it should, but in the meantime, I've created the following workaround using the promise-retry
library (which uses an exponential backoff strategy).
const promiseRetry = require('promise-retry') const MongoClient = require('mongodb').MongoClient const options = { useNewUrlParser: true, reconnectTries: 60, reconnectInterval: 1000, poolSize: 10, bufferMaxEntries: 0 } const promiseRetryOptions = { retries: options.reconnectTries, factor: 1.5, minTimeout: options.reconnectInterval, maxTimeout: 5000 } const connect = (url) => { return promiseRetry((retry, number) => { console.log(`MongoClient connecting to ${url} - retry number: ${number}`) return MongoClient.connect(url, options).catch(retry) }, promiseRetryOptions) } module.exports = { connect }
Mongo Initial Connect Error: failed to connect to server [db:27017] on first connect
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