-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: 3.3.5
-
Component/s: None
-
Empty show more show less
If useUnifiedTopology is set while connected to a replicaset (MongoDB Atlas) the driver sometimes fails to properly reject operations when internet connection is lost. The operations is being kept as pending and then successfully executing when connection is reestablished after several minutes later. The expected result would be for the operation to throw a MongoTimeoutError for server selection after serverSelectionTimeoutMS has expired. The error scenario seems to happen when the operation is executed after the disconnection but before the first serverHeartbeatFailed event.
Besides driver version 3.3.5, this is still reproducible reproducible on master (commit 994c076af3532d753932b5b271f3ad57c5ae4b2a).
Reproduction steps on Node.js REPL:
$ node Welcome to Node.js v12.10.0. Type ".help" for more information. > MongoClient = require('mongodb').MongoClient; client = new MongoClient(`mongodb+srv://${dbUser}:${dbPasswd}@${dbHost}/${dbName}`, { useUnifiedTopology: true, serverSelectionTimeoutMS: 2000, connectTimeoutMS: 2000 }); oldEmitter = client.emit; client.emit = (...args) => { console.log(args[0]); oldEmitter.apply(client, args); }; client.connect().then(conn => db = conn.db()).catch(console.log); Promise { <pending> } topologyOpening topologyDescriptionChanged serverOpening serverOpening serverOpening serverDescriptionChanged topologyDescriptionChanged open authenticated serverDescriptionChanged topologyDescriptionChanged serverDescriptionChanged topologyDescriptionChanged // Internet connection cut down > db.db().collection('users').find().project({_id:1}).limit(2).toArray().then(console.log).catch(console.log) Promise { <pending> } serverHeartbeatStarted serverHeartbeatStarted serverHeartbeatStarted serverHeartbeatFailed serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverHeartbeatFailed serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged // ... several minutes later serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged > db.db().collection('users').find().project({_id:1}).limit(2).toArray().then(console.log).catch(console.log) Promise { <pending> } serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged // ... several minutes later serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening topologyDescriptionChanged serverDescriptionChanged serverClosed serverOpening // Internet connection reestablished topologyDescriptionChanged [ { _id: 5dd7ec0819d841b947fd0296 }, { _id: 5dd7edbf19d8419d6dfd0297 } ] serverHeartbeatSucceeded serverDescriptionChanged topologyDescriptionChanged serverDescriptionChanged topologyDescriptionChanged [ { _id: 5dd7ec0819d841b947fd0296 }, { _id: 5dd7edbf19d8419d6dfd0297 } ] serverHeartbeatStarted serverHeartbeatSucceeded serverHeartbeatStarted serverHeartbeatSucceeded serverHeartbeatStarted serverHeartbeatSucceeded