-
Type: Bug
-
Resolution: Cannot Reproduce
-
Priority: Major - P3
-
None
-
Affects Version/s: 2.0.33
-
Component/s: None
-
Labels:
-
Empty show more show less
When using the mongodb node driver to connect to a replica set when the replica set is being constructed, the driver ends up in a unusable state where any request is never replied.
Scenario:
- vagrant + chef to create a MongoDB 2.6 server, and configure a replicaSet (named "indexers") with localhost as only server
- as soon as the replicaSet configuration request finished (the replicaSet is still constructing itself), start a long lived node process using mongodb connections to the replica set ( url: "mongodb://localhost:27017/TRSL?replicaSet=indexers", pool_size: 15), so we correctly ask to connect to a replica set, and not directly to the server)
- the node process tries to query the replica set, and many MongoError are logged during the ~2 seconds replicaSet construction time (60 times):
MongoError: not master and slaveOk=false at Function.MongoError.create (/opt/systran/apps-node/translation-resource-store/node_modules/mongodb/node_modules/mongodb-core/lib/error.js:31:11) at queryCallback (/opt/systran/apps-node/translation-resource-store/node_modules/mongodb/node_modules/mongodb-core/lib/cursor.js:170:34) at Callbacks.emit (/opt/systran/apps-node/translation-resource-store/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:94:3) at null.messageHandler (/opt/systran/apps-node/translation-resource-store/node_modules/mongodb/node_modules/mongodb-core/lib/topologies/server.js:235:23) at Socket.<anonymous> (/opt/systran/apps-node/translation-resource-store/node_modules/mongodb/node_modules/mongodb-core/lib/connection/connection.js:294:20) at Socket.emit (events.js:95:17) at Socket.<anonymous> (_stream_readable.js:765:14) at Socket.emit (events.js:92:17) at emitReadable_ (_stream_readable.js:427:10) at emitReadable (_stream_readable.js:423:5)
- MongoErrors stop when the replicaSet is ready
- MongoDB requests are never answered though: for example, a db.collection.find().count() never returns
I digged a little on the running node process at this point in the scenario using node inspector:
In mongodb/lib/cursor.js: Cursor.prototype.count:
// Get a server var server = self.s.topology.getServer(opts); // Get a connection var connection = self.s.topology.getConnection(opts);
This code calls mongodb-core/lib/topologies/server.js instead of mongodb-core/lib/topologies/replset.js, so somewhere the replica set information was lost...
In server.js the connection pool is broken:
, but it's used anyway.
In pool.js: Pool.prototype.get: there is a "// if(this.dead) return null;", but it's commented, and there is no check on null in the callers.
When starting the node process when the replica set is already constructed, the topology used is correctly a ReplSet object from mongodb-core/lib/topologies/replset.js.
This is always reproductible when connecting during the replica set construction.
I will try to reproduce with mongodb driver debug traces, maybe it will give us more information to when the topology was switched from ReplSet to Server, and why it leads to using a destroyed connection pool.