Skip to content

Commit 666f01c

Browse files
refactor(NODE-5063): make DestroyOptions required on connection.destroy (#3568)
1 parent 9ce0bcc commit 666f01c

File tree

12 files changed

+60
-94
lines changed

12 files changed

+60
-94
lines changed

src/cmap/connect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function performInitialHandshake(
9696
) {
9797
const callback: Callback<Document> = function (err, ret) {
9898
if (err && conn) {
99-
conn.destroy();
99+
conn.destroy({ force: false });
100100
}
101101
_callback(err, ret);
102102
};

src/cmap/connection.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export interface ConnectionOptions
133133
/** @internal */
134134
export interface DestroyOptions {
135135
/** Force the destruction. */
136-
force?: boolean;
136+
force: boolean;
137137
}
138138

139139
/** @public */
@@ -443,16 +443,10 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
443443
callback(undefined, message.documents[0]);
444444
}
445445

446-
destroy(options?: DestroyOptions, callback?: Callback): void {
447-
if (typeof options === 'function') {
448-
callback = options;
449-
options = { force: false };
450-
}
451-
446+
destroy(options: DestroyOptions, callback?: Callback): void {
452447
this.removeAllListeners(Connection.PINNED);
453448
this.removeAllListeners(Connection.UNPINNED);
454449

455-
options = Object.assign({ force: false }, options);
456450
if (this[kStream] == null || this.destroyed) {
457451
this.destroyed = true;
458452
if (typeof callback === 'function') {

src/cmap/connection_pool.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
510510
ConnectionPool.CONNECTION_CLOSED,
511511
new ConnectionClosedEvent(this, conn, 'poolClosed')
512512
);
513-
conn.destroy(options, cb);
513+
conn.destroy({ force: !!options.force }, cb);
514514
},
515515
err => {
516516
this[kConnections].clear();
@@ -586,7 +586,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
586586
new ConnectionClosedEvent(this, connection, reason)
587587
);
588588
// destroy the connection
589-
process.nextTick(() => connection.destroy());
589+
process.nextTick(() => connection.destroy({ force: false }));
590590
}
591591

592592
private connectionIsStale(connection: Connection) {

src/sdam/server.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,10 @@ export class Server extends TypedEventEmitter<ServerEvents> {
241241

242242
/** Destroy the server connection */
243243
destroy(options?: DestroyOptions, callback?: Callback): void {
244-
if (typeof options === 'function') (callback = options), (options = {});
244+
if (typeof options === 'function') {
245+
callback = options;
246+
options = { force: false };
247+
}
245248
options = Object.assign({}, { force: false }, options);
246249

247250
if (this.s.state === STATE_CLOSED) {

src/sdam/topology.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -466,26 +466,17 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
466466
}
467467

468468
/** Close this topology */
469-
close(callback: Callback): void;
470469
close(options: CloseOptions): void;
471470
close(options: CloseOptions, callback: Callback): void;
472-
close(options?: CloseOptions | Callback, callback?: Callback): void {
473-
if (typeof options === 'function') {
474-
callback = options;
475-
options = {};
476-
}
477-
478-
if (typeof options === 'boolean') {
479-
options = { force: options };
480-
}
481-
options = options ?? {};
471+
close(options?: CloseOptions, callback?: Callback): void {
472+
options = options ?? { force: false };
482473

483474
if (this.s.state === STATE_CLOSED || this.s.state === STATE_CLOSING) {
484475
return callback?.();
485476
}
486477

487478
const destroyedServers = Array.from(this.s.servers.values(), server => {
488-
return promisify(destroyServer)(server, this, options as CloseOptions);
479+
return promisify(destroyServer)(server, this, { force: !!options?.force });
489480
});
490481

491482
Promise.all(destroyedServers)
@@ -740,7 +731,7 @@ function destroyServer(
740731
options?: DestroyOptions,
741732
callback?: Callback
742733
) {
743-
options = options ?? {};
734+
options = options ?? { force: false };
744735
for (const event of LOCAL_SERVER_EVENTS) {
745736
server.removeAllListeners(event);
746737
}

test/integration/crud/misc_cursors.test.js

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const sinon = require('sinon');
1010
const { Writable } = require('stream');
1111
const { once, on } = require('events');
1212
const { setTimeout } = require('timers');
13-
const { ReadPreference } = require('../../mongodb');
13+
const { ReadPreference, MongoExpiredSessionError } = require('../../mongodb');
1414
const { ServerType } = require('../../mongodb');
1515
const { formatSort } = require('../../mongodb');
1616
const { getSymbolFrom } = require('../../tools/utils');
@@ -1852,61 +1852,31 @@ describe('Cursor', function () {
18521852
}
18531853
});
18541854

1855-
it('should close dead tailable cursors', {
1856-
metadata: {
1857-
os: '!win32' // NODE-2943: timeout on windows
1858-
},
1859-
1860-
test: function (done) {
1861-
// http://www.mongodb.org/display/DOCS/Tailable+Cursors
1862-
1863-
const configuration = this.configuration;
1864-
client.connect((err, client) => {
1865-
expect(err).to.not.exist;
1866-
this.defer(() => client.close());
1867-
1868-
const db = client.db(configuration.db);
1869-
const options = { capped: true, size: 10000000 };
1870-
db.createCollection(
1871-
'test_if_dead_tailable_cursors_close',
1872-
options,
1873-
function (err, collection) {
1874-
expect(err).to.not.exist;
1855+
it('closes cursors when client is closed even if it has not been exhausted', async function () {
1856+
await client
1857+
.db()
1858+
.dropCollection('test_cleanup_tailable')
1859+
.catch(() => null);
18751860

1876-
let closeCount = 0;
1877-
const docs = Array.from({ length: 100 }).map(() => ({ a: 1 }));
1878-
collection.insertMany(docs, { w: 'majority', wtimeoutMS: 5000 }, err => {
1879-
expect(err).to.not.exist;
1880-
1881-
const cursor = collection.find({}, { tailable: true, awaitData: true });
1882-
const stream = cursor.stream();
1861+
const collection = await client
1862+
.db()
1863+
.createCollection('test_cleanup_tailable', { capped: true, size: 1000, max: 3 });
18831864

1884-
stream.resume();
1885-
1886-
var validator = () => {
1887-
closeCount++;
1888-
if (closeCount === 2) {
1889-
done();
1890-
}
1891-
};
1865+
// insert only 2 docs in capped coll of 3
1866+
await collection.insertMany([{ a: 1 }, { a: 1 }]);
18921867

1893-
// we validate that the stream "ends" either cleanly or with an error
1894-
stream.on('end', validator);
1895-
stream.on('error', validator);
1868+
const cursor = collection.find({}, { tailable: true, awaitData: true, maxAwaitTimeMS: 2000 });
18961869

1897-
cursor.on('close', validator);
1870+
await cursor.next();
1871+
await cursor.next();
1872+
// will block for maxAwaitTimeMS (except we are closing the client)
1873+
const rejectedEarlyBecauseClientClosed = cursor.next().catch(error => error);
18981874

1899-
const docs = Array.from({ length: 100 }).map(() => ({ a: 1 }));
1900-
collection.insertMany(docs, err => {
1901-
expect(err).to.not.exist;
1875+
await client.close();
1876+
expect(cursor).to.have.property('killed', true);
19021877

1903-
setTimeout(() => client.close());
1904-
});
1905-
});
1906-
}
1907-
);
1908-
});
1909-
}
1878+
const error = await rejectedEarlyBecauseClientClosed;
1879+
expect(error).to.be.instanceOf(MongoExpiredSessionError);
19101880
});
19111881

19121882
it('shouldAwaitData', {

test/integration/node-specific/topology.test.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@ describe('Topology', function () {
1010
const states = [];
1111
topology.on('stateChanged', (_, newState) => states.push(newState));
1212
topology.connect(err => {
13-
expect(err).to.not.exist;
14-
topology.close(err => {
13+
try {
1514
expect(err).to.not.exist;
16-
expect(topology.isDestroyed()).to.be.true;
17-
expect(states).to.eql(['connecting', 'connected', 'closing', 'closed']);
18-
done();
15+
} catch (error) {
16+
done(error);
17+
}
18+
topology.close({}, err => {
19+
try {
20+
expect(err).to.not.exist;
21+
expect(topology.isDestroyed()).to.be.true;
22+
expect(states).to.eql(['connecting', 'connected', 'closing', 'closed']);
23+
done();
24+
} catch (error) {
25+
done(error);
26+
}
1927
});
2028
});
2129
}

test/unit/assorted/polling_srv_records_for_mongos_discovery.prose.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ describe('Polling Srv Records for Mongos Discovery', () => {
103103

104104
afterEach(function (done) {
105105
if (context.topology) {
106-
context.topology.close(done);
106+
context.topology.close({}, done);
107107
} else {
108108
done();
109109
}

test/unit/assorted/server_selection_spec_helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ function executeServerSelectionTest(testDefinition, testDone) {
109109
});
110110

111111
function done(err) {
112-
topology.close(e => testDone(e || err));
112+
topology.close({}, e => testDone(e || err));
113113
}
114114

115115
topology.connect(err => {

test/unit/error.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ describe('MongoErrors', () => {
381381

382382
makeAndConnectReplSet((err, topology) => {
383383
// cleanup the server before calling done
384-
const cleanup = err => topology.close(err2 => done(err || err2));
384+
const cleanup = err => topology.close({}, err2 => done(err || err2));
385385

386386
if (err) {
387387
return cleanup(err);

0 commit comments

Comments
 (0)