Skip to content

Commit

Permalink
refactor(pool): maintain legacy pool reconnect behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
mbroadst committed Oct 9, 2019
1 parent 8153065 commit 37dbe49
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
48 changes: 36 additions & 12 deletions lib/core/connection/pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const inherits = require('util').inherits;
const EventEmitter = require('events').EventEmitter;
const MongoError = require('../error').MongoError;
const MongoNetworkError = require('../error').MongoNetworkError;
const MongoTimeoutError = require('../error').MongoTimeoutError;
const MongoWriteConcernError = require('../error').MongoWriteConcernError;
const Logger = require('./logger');
const f = require('util').format;
Expand Down Expand Up @@ -113,7 +113,9 @@ var Pool = function(topology, options) {
reconnectInterval: 1000,
reconnectTries: 30,
// Enable domains
domainsEnabled: false
domainsEnabled: false,
// feature flag for determining if we are running with the unified topology or not
legacyCompatMode: true
},
options
);
Expand All @@ -123,6 +125,7 @@ var Pool = function(topology, options) {
// Current reconnect retries
this.retriesLeft = this.options.reconnectTries;
this.reconnectId = null;
this.reconnectError = null;
// No bson parser passed in
if (
!options.bson ||
Expand Down Expand Up @@ -289,6 +292,7 @@ function connectionFailureHandler(pool, event, err, conn) {

// Start reconnection attempts
if (!pool.reconnectId && pool.options.reconnect) {
pool.reconnectError = err;
pool.reconnectId = setTimeout(attemptReconnect(pool), pool.options.reconnectInterval);
}

Expand All @@ -315,10 +319,11 @@ function attemptReconnect(pool, callback) {
if (pool.retriesLeft <= 0) {
pool.destroy();

const error = new MongoNetworkError(
const error = new MongoTimeoutError(
`failed to reconnect after ${pool.options.reconnectTries} attempts with interval ${
pool.options.reconnectInterval
} ms`
} ms`,
pool.reconnectError
);

pool.emit('reconnectFailed', error);
Expand All @@ -333,7 +338,17 @@ function attemptReconnect(pool, callback) {
pool.reconnectId = null;

// now retry creating a connection
createConnection(pool, callback);
createConnection(pool, (err, conn) => {
if (err == null) {
pool.reconnectId = null;
pool.retriesLeft = pool.options.reconnectTries;
pool.emit('reconnect', pool);
}

if (typeof callback === 'function') {
callback(err, conn);
}
});
};
}

Expand Down Expand Up @@ -943,7 +958,23 @@ function createConnection(pool, callback) {
pool.logger.debug(`connection attempt failed with error [${JSON.stringify(err)}]`);
}

if (pool.options.legacyCompatMode === false) {
// The unified topology uses the reported `error` from a pool to track what error
// reason is returned to the user during selection timeout. We only want to emit
// this if the pool is active because the listeners are removed on destruction.
if (pool.state !== DESTROYED && pool.state !== DESTROYING) {
pool.emit('error', err);
}
}

// check if reconnect is enabled, and attempt retry if so
if (!pool.reconnectId && pool.options.reconnect) {
if (pool.state === CONNECTING && pool.options.legacyCompatMode) {
callback(err);
return;
}

pool.reconnectError = err;
pool.reconnectId = setTimeout(
attemptReconnect(pool, callback),
pool.options.reconnectInterval
Expand Down Expand Up @@ -978,13 +1009,6 @@ function createConnection(pool, callback) {

pool.availableConnections.push(connection);

// if there is a reconnect in progress, reset state and emit event
if (pool.reconnectId) {
pool.reconnectId = null;
pool.retriesLeft = pool.options.reconnectTries;
pool.emit('reconnect', pool);
}

// if a callback was provided, return the connection
if (typeof callback === 'function') {
callback(null, connection);
Expand Down
1 change: 1 addition & 0 deletions lib/core/sdam/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class Server extends EventEmitter {

// NOTE: this should only be the case if we are connecting to a single server
poolOptions.reconnect = true;
poolOptions.legacyCompatMode = false;

this.s.pool = new Pool(this, poolOptions);

Expand Down

0 comments on commit 37dbe49

Please sign in to comment.