diff --git a/lib/sdam/server.js b/lib/sdam/server.js index bb0d1bb3f..d82808f02 100644 --- a/lib/sdam/server.js +++ b/lib/sdam/server.js @@ -126,10 +126,11 @@ class Server extends EventEmitter { this.s.pool.on('error', errorEventHandler(this)); this.s.pool.on('parseError', parseErrorEventHandler(this)); - // it is unclear whether consumers should even know about these events - // this.s.pool.on('timeout', timeoutEventHandler(this)); - // this.s.pool.on('reconnect', reconnectEventHandler(this)); - // this.s.pool.on('reconnectFailed', errorEventHandler(this)); + // relay events to ensure topology reconnection/connection status consistency. + // for more details, check: NODE-2147: Unexpected behaviours using useUnifiedTopology: true + this.s.pool.on('timeout', timeoutEventHandler(this)); + this.s.pool.on('reconnect', reconnectEventHandler(this)); + this.s.pool.on('reconnectFailed', errorEventHandler(this)); // relay all command monitoring events relayEvents(this.s.pool, this, ['commandStarted', 'commandSucceeded', 'commandFailed']); @@ -389,4 +390,19 @@ function parseErrorEventHandler(server) { }; } +function timeoutEventHandler(server) { + return function() { + server.s.state = STATE_DISCONNECTED; + server.emit('error', new MongoNetworkError('Pool timeout event triggered.')); + server.emit('close'); + }; +} + +function reconnectEventHandler(server) { + return function() { + server.s.state = STATE_CONNECTING; + server.emit('reconnect'); + }; +} + module.exports = Server; diff --git a/lib/sdam/topology.js b/lib/sdam/topology.js index 5083b61ba..eeaeb08ad 100644 --- a/lib/sdam/topology.js +++ b/lib/sdam/topology.js @@ -54,7 +54,8 @@ const LOCAL_SERVER_EVENTS = SERVER_RELAY_EVENTS.concat([ 'connect', 'descriptionReceived', 'close', - 'ended' + 'ended', + 'reconnectFailed' ]); /** @@ -843,6 +844,11 @@ function updateServers(topology, incomingServerDescription) { function serverConnectEventHandler(server, topology) { return function(/* isMaster, err */) { + // close topology on reconnectFailed. + server.s.pool.on('reconnectFailed', () => { + topology.close(); + }); + server.monitor({ initial: true, heartbeatFrequencyMS: topology.description.heartbeatFrequencyMS diff --git a/lib/topologies/server.js b/lib/topologies/server.js index 2144e750f..5606880e3 100644 --- a/lib/topologies/server.js +++ b/lib/topologies/server.js @@ -382,7 +382,7 @@ var eventHandler = function(self, event) { event === 'timeout' || event === 'reconnect' || event === 'attemptReconnect' || - 'reconnectFailed' + event === 'reconnectFailed' ) { // Remove server instance from accounting if (