Skip to content

Commit da931ea

Browse files
committed
fix(pool): support a drain event for use with unified topology
Until we integrate the new connection pool conforming to the CMAP specification, any type of error/close/timeout coming from a pool signals pool invalidation. If the pool is configured for unified then it should invalidate the server by emitting a `drain` event which is translated to an `error in the Server instance, causing the topology to cycle the server. NODE-2332
1 parent 2aeb1f2 commit da931ea

File tree

4 files changed

+17
-2
lines changed

4 files changed

+17
-2
lines changed

lib/core/connection/pool.js

+9
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,15 @@ function connectionFailureHandler(pool, event, err, conn) {
256256
const workItem = conn.workItems.shift();
257257
if (workItem.cb) workItem.cb(err);
258258
}
259+
260+
if (pool.state !== DRAINING && pool.options.legacyCompatMode === false) {
261+
// since an error/close/timeout means pool invalidation in a
262+
// pre-CMAP world, we will issue a custom `drain` event here to
263+
// signal that the server should be recycled
264+
stateTransition(pool, DRAINING);
265+
pool.emit('drain', err);
266+
return;
267+
}
259268
}
260269

261270
// Did we catch a timeout, increment the numberOfConsecutiveTimeouts

lib/core/error.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,9 @@ function isNodeShuttingDownError(err) {
207207
* @param {Server} server
208208
*/
209209
function isSDAMUnrecoverableError(error, server) {
210-
if (error instanceof MongoParseError) {
210+
// NOTE: null check is here for a strictly pre-CMAP world, a timeout or
211+
// close event are considered unrecoverable
212+
if (error instanceof MongoParseError || error == null) {
211213
return true;
212214
}
213215

lib/core/sdam/server.js

+4
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ class Server extends EventEmitter {
158158
// setup listeners
159159
this.s.pool.on('parseError', parseErrorEventHandler(this));
160160

161+
this.s.pool.on('drain', err => {
162+
this.emit('error', err);
163+
});
164+
161165
// it is unclear whether consumers should even know about these events
162166
// this.s.pool.on('timeout', timeoutEventHandler(this));
163167
// this.s.pool.on('reconnect', reconnectEventHandler(this));

test/functional/spec-runner/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ function parseSessionOptions(options) {
221221
return result;
222222
}
223223

224-
const IGNORED_COMMANDS = new Set(['ismaster', 'configureFailPoint']);
224+
const IGNORED_COMMANDS = new Set(['ismaster', 'configureFailPoint', 'endSessions']);
225225

226226
let displayCommands = false;
227227
function runTestSuiteTest(configuration, spec, context) {

0 commit comments

Comments
 (0)