From 27cefad180684ed668ab1096a95db1bc0b4cc30b Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Wed, 16 Oct 2019 13:51:26 -0400 Subject: [PATCH] fix(connection): ensure repeated `close` events from useUnifiedTopology don't disconnect Mongoose from replica set Fix #8224 Re: NODE-2251 --- lib/connection.js | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/lib/connection.js b/lib/connection.js index 43e4028510b..d3fde9d4c15 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -639,18 +639,28 @@ Connection.prototype.openUri = function(uri, options, callback) { _this.db = db; // `useUnifiedTopology` events - if (options.useUnifiedTopology && - get(db, 's.topology.s.description.type') === 'Single') { - const server = Array.from(db.s.topology.s.servers.values())[0]; - server.s.pool.on('reconnect', () => { - _handleReconnect(); - }); - server.s.pool.on('reconnectFailed', () => { - _this.emit('reconnectFailed'); - }); - server.s.pool.on('timeout', () => { - _this.emit('timeout'); - }); + const type = get(db, 's.topology.s.description.type', ''); + if (options.useUnifiedTopology) { + if (type === 'Single') { + const server = Array.from(db.s.topology.s.servers.values())[0]; + server.s.pool.on('reconnect', () => { + _handleReconnect(); + }); + server.s.pool.on('reconnectFailed', () => { + _this.emit('reconnectFailed'); + }); + server.s.pool.on('timeout', () => { + _this.emit('timeout'); + }); + } else if (type.startsWith('ReplicaSet')) { + db.on('close', function() { + const type = get(db, 's.topology.s.description.type', ''); + if (type !== 'ReplicaSetWithPrimary') { + // Implicitly emits 'disconnected' + _this.readyState = STATES.disconnected; + } + }); + } } // Backwards compat for mongoose 4.x @@ -674,10 +684,12 @@ Connection.prototype.openUri = function(uri, options, callback) { _this.emit('attemptReconnect'); }); } - db.on('close', function() { - // Implicitly emits 'disconnected' - _this.readyState = STATES.disconnected; - }); + if (!options.useUnifiedTopology || !type.startsWith('ReplicaSet')) { + db.on('close', function() { + // Implicitly emits 'disconnected' + _this.readyState = STATES.disconnected; + }); + } client.on('left', function() { if (_this.readyState === STATES.connected && get(db, 's.topology.s.coreTopology.s.replicaSetState.topologyType') === 'ReplicaSetNoPrimary') {