From 791029fcac2c898c3f60463e5d59da342700c3d9 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Tue, 3 Sep 2024 16:23:47 -0400 Subject: [PATCH 01/15] initial commit --- src/cmap/commands.ts | 2 +- .../read-write-concern/write_concern.test.ts | 5 +++-- test/unit/commands.test.ts | 13 +++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index 19dd8e1a657..954455bc154 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -450,7 +450,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || false; + this.moreToCome = options.moreToCome || options.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index 58901e513b5..c995a1b928a 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -11,7 +11,7 @@ import { import * as mock from '../../tools/mongodb-mock/index'; import { filterForCommands } from '../shared'; -describe('Write Concern', function () { +describe.only('Write Concern', function () { context('when the WriteConcern is set in the uri', function () { let client; const events: CommandStartedEvent[] = []; @@ -29,7 +29,8 @@ describe('Write Concern', function () { expect(events[0]).to.containSubset({ commandName: 'insert', command: { - writeConcern: { w: 0 } + writeConcern: { w: 0 }, + moreToCome: true } }); }); diff --git a/test/unit/commands.test.ts b/test/unit/commands.test.ts index f6ba300b7aa..93831530955 100644 --- a/test/unit/commands.test.ts +++ b/test/unit/commands.test.ts @@ -6,6 +6,8 @@ import * as compression from '../../src/cmap/wire_protocol/compression'; import { compress, Compressor, + Connection, + MongoClient, OP_MSG, OP_QUERY, OpCompressedRequest, @@ -109,3 +111,14 @@ describe('class OpCompressedRequest', () => { } }); }); + +describe.only('fire-and-forget', () => { + describe('OpMsgRequest', () => { + context('when writeConcern.w is 0', () => { + it('moreToCome is set to true', async () => { + const request = new OpMsgRequest('db', { a: 1 }, { writeConcern: { w: 0 } }); + expect(request.moreToCome).to.be.true; + }); + }); + }); +}); From d1a1931a460b0b17c6083b603e54bdbdf6932423 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Tue, 3 Sep 2024 18:15:27 -0400 Subject: [PATCH 02/15] enforce no response when moreToCome is set --- src/cmap/connection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index 1e4afc7f387..8a52f4e71bc 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -438,7 +438,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse) { + if (options.noResponse || ('moreToCome' in message && message?.moreToCome)) { yield MongoDBResponse.empty; return; } From ebd4b44854cf8048016eff515e50d9a4aa82ea6f Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 6 Sep 2024 16:54:49 -0400 Subject: [PATCH 03/15] ready for review lint fix lont fix 2 --- src/cmap/commands.ts | 2 +- src/cmap/connection.ts | 12 +- .../read-write-concern/write_concern.test.ts | 143 +++++++++++++++++- test/unit/commands.test.ts | 10 +- 4 files changed, 152 insertions(+), 15 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index ff9636f1828..a7554ff8819 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -465,7 +465,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || options.writeConcern?.w === 0 || false; + this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index f6a178f9797..be819c7a6cc 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -438,7 +438,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse || ('moreToCome' in message && message?.moreToCome)) { + if (options.noResponse) { yield MongoDBResponse.empty; return; } @@ -500,9 +500,13 @@ export class Connection extends TypedEventEmitter { let document: MongoDBResponse | undefined = undefined; /** Cached result of a toObject call */ let object: Document | undefined = undefined; + const wireOptions = options; + if (message instanceof OpMsgRequest) { + wireOptions.noResponse = options.noResponse || message.moreToCome; + } try { this.throwIfAborted(); - for await (document of this.sendWire(message, options, responseType)) { + for await (document of this.sendWire(message, wireOptions, responseType)) { object = undefined; if (options.session != null) { updateSessionFromResponse(options.session, document); @@ -526,7 +530,7 @@ export class Connection extends TypedEventEmitter { new CommandSucceededEvent( this, message, - options.noResponse ? undefined : (object ??= document.toObject(bsonOptions)), + wireOptions.noResponse ? { ok: 1 } : (object ??= document.toObject(bsonOptions)), started, this.description.serverConnectionId ) @@ -629,8 +633,8 @@ export class Connection extends TypedEventEmitter { }); const buffer = Buffer.concat(await finalCommand.toBin()); - if (this.socket.write(buffer)) return; + return await once(this.socket, 'drain'); } diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index c995a1b928a..b00e971312d 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -1,17 +1,21 @@ import { expect } from 'chai'; import { on, once } from 'events'; +import { gte } from 'semver'; +import * as sinon from 'sinon'; import { type Collection, type CommandStartedEvent, + type CommandSucceededEvent, type Db, LEGACY_HELLO_COMMAND, - MongoClient + MongoClient, + OpMsgRequest } from '../../mongodb'; import * as mock from '../../tools/mongodb-mock/index'; import { filterForCommands } from '../shared'; -describe.only('Write Concern', function () { +describe('Write Concern', function () { context('when the WriteConcern is set in the uri', function () { let client; const events: CommandStartedEvent[] = []; @@ -29,8 +33,7 @@ describe.only('Write Concern', function () { expect(events[0]).to.containSubset({ commandName: 'insert', command: { - writeConcern: { w: 0 }, - moreToCome: true + writeConcern: { w: 0 } } }); }); @@ -169,4 +172,136 @@ describe.only('Write Concern', function () { }); }); }); + + describe('fire-and-forget protocol', function () { + context('when writeConcern = 0 and OP_MSG is used', function () { + const writeOperations: { name: string; command: any; expectedReturnVal: any }[] = [ + { + name: 'insertOne', + command: client => client.db('test').collection('test').insertOne({ a: 1 }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'insertMany', + command: client => + client + .db('test') + .collection('test') + .insertMany([{ a: 1 }, { b: 2 }]), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'updateOne', + command: client => + client + .db('test') + .collection('test') + .updateOne({ i: 128 }, { $set: { c: 2 } }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'updateMany', + command: client => + client + .db('test') + .collection('test') + .updateMany({ name: 'foobar' }, { $set: { name: 'fizzbuzz' } }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'deleteOne', + command: client => client.db('test').collection('test').deleteOne({ a: 1 }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'deleteMany', + command: client => client.db('test').collection('test').deleteMany({ name: 'foobar' }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'replaceOne', + command: client => client.db('test').collection('test').replaceOne({ a: 1 }, { b: 2 }), + expectedReturnVal: { acknowledged: false } + }, + { + name: 'removeUser', + command: client => client.db('test').removeUser('albert'), + expectedReturnVal: true + }, + { + name: 'findAndModify', + command: client => + client + .db('test') + .collection('test') + .findOneAndUpdate({}, { $setOnInsert: { a: 1 } }, { upsert: true }), + expectedReturnVal: null + }, + { + name: 'dropDatabase', + command: client => client.db('test').dropDatabase(), + expectedReturnVal: true + }, + { + name: 'dropCollection', + command: client => client.db('test').dropCollection('test'), + expectedReturnVal: true + }, + { + name: 'dropIndexes', + command: client => client.db('test').collection('test').dropIndex('a'), + expectedReturnVal: { ok: 1 } + }, + { + name: 'createIndexes', + command: client => client.db('test').collection('test').createIndex({ a: 1 }), + expectedReturnVal: 'a_1' + }, + { + name: 'createCollection', + command: client => client.db('test').createCollection('test'), + expectedReturnVal: {} + } + ]; + + for (const op of writeOperations) { + context(`when the write operation ${op.name} is run`, function () { + let client; + let spy; + + beforeEach(async function () { + if (gte('3.6.0', this.configuration.version)) { + this.currentTest.skipReason = 'Test requires OP_MSG, needs to be on MongoDB 3.6+'; + this.skip(); + } + spy = sinon.spy(OpMsgRequest.prototype, 'toBin'); + client = this.configuration.newClient({ monitorCommands: true, w: 0 }); + await client.connect(); + }); + + afterEach(function () { + sinon.restore(); + client.close(); + }); + + it('the request should have moreToCome bit set', async function () { + await op.command(client); + expect(spy.returnValues[spy.returnValues.length - 1][0][16]).to.equal(2); + }); + + it('the return value of the command should be nullish', async function () { + const result = await op.command(client); + expect(result).to.containSubset(op.expectedReturnVal); + }); + + it('commandSucceededEvent should have reply with only {ok: 1}', async function () { + const events: CommandSucceededEvent[] = []; + client.on('commandSucceeded', event => events.push(event)); + await op.command(client); + expect(events[0]).to.containSubset({ reply: { ok: 1 } }); + }); + }); + } + }); + }); }); diff --git a/test/unit/commands.test.ts b/test/unit/commands.test.ts index 93831530955..2b2cf5f58b4 100644 --- a/test/unit/commands.test.ts +++ b/test/unit/commands.test.ts @@ -6,8 +6,6 @@ import * as compression from '../../src/cmap/wire_protocol/compression'; import { compress, Compressor, - Connection, - MongoClient, OP_MSG, OP_QUERY, OpCompressedRequest, @@ -112,11 +110,11 @@ describe('class OpCompressedRequest', () => { }); }); -describe.only('fire-and-forget', () => { - describe('OpMsgRequest', () => { - context('when writeConcern.w is 0', () => { +describe('OpMsgRequest', () => { + describe('fire-and-forget', () => { + context('when writeConcern = 0', () => { it('moreToCome is set to true', async () => { - const request = new OpMsgRequest('db', { a: 1 }, { writeConcern: { w: 0 } }); + const request = new OpMsgRequest('db', { a: 1, writeConcern: { w: 0 } }, {}); expect(request.moreToCome).to.be.true; }); }); From 86e1a917981c0e2a485dde994e72ac014b1197d2 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 6 Sep 2024 17:04:51 -0400 Subject: [PATCH 04/15] tsdoc updateg --- src/write_concern.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/write_concern.ts b/src/write_concern.ts index 456b7e8d83b..8f2b288736a 100644 --- a/src/write_concern.ts +++ b/src/write_concern.ts @@ -58,7 +58,10 @@ interface CommandWriteConcernOptions { * @see https://www.mongodb.com/docs/manual/reference/write-concern/ */ export class WriteConcern { - /** Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. */ + /** + * Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. + * If w is 0 and is set on the command in the request, the server will not send a response. + */ readonly w?: W; /** Request acknowledgment that the write operation has been written to the on-disk journal */ readonly journal?: boolean; From d892ccca23654b109bf09d4b9b10e1b1bd5af47f Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 6 Sep 2024 17:19:46 -0400 Subject: [PATCH 05/15] lint fix remove extra newline remove extra newline --- src/cmap/connection.ts | 2 +- src/write_concern.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index be819c7a6cc..3cada6392cc 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -633,8 +633,8 @@ export class Connection extends TypedEventEmitter { }); const buffer = Buffer.concat(await finalCommand.toBin()); - if (this.socket.write(buffer)) return; + if (this.socket.write(buffer)) return; return await once(this.socket, 'drain'); } diff --git a/src/write_concern.ts b/src/write_concern.ts index 8f2b288736a..390646a3be0 100644 --- a/src/write_concern.ts +++ b/src/write_concern.ts @@ -58,10 +58,10 @@ interface CommandWriteConcernOptions { * @see https://www.mongodb.com/docs/manual/reference/write-concern/ */ export class WriteConcern { - /** - * Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. - * If w is 0 and is set on the command in the request, the server will not send a response. - */ + /** + * Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. + * If w is 0 and is set on a write operation, the server will not send a response. + */ readonly w?: W; /** Request acknowledgment that the write operation has been written to the on-disk journal */ readonly journal?: boolean; From 5df9384349fce91fa27a53e1bdaa99b6749e93a9 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 9 Sep 2024 10:22:18 -0400 Subject: [PATCH 06/15] fix failing test --- src/cmap/connection.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index 3cada6392cc..49726fdded1 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -438,7 +438,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse) { + if (options.noResponse || ('moreToCome' in message && message.moreToCome)) { yield MongoDBResponse.empty; return; } @@ -500,13 +500,9 @@ export class Connection extends TypedEventEmitter { let document: MongoDBResponse | undefined = undefined; /** Cached result of a toObject call */ let object: Document | undefined = undefined; - const wireOptions = options; - if (message instanceof OpMsgRequest) { - wireOptions.noResponse = options.noResponse || message.moreToCome; - } try { this.throwIfAborted(); - for await (document of this.sendWire(message, wireOptions, responseType)) { + for await (document of this.sendWire(message, options, responseType)) { object = undefined; if (options.session != null) { updateSessionFromResponse(options.session, document); @@ -530,7 +526,11 @@ export class Connection extends TypedEventEmitter { new CommandSucceededEvent( this, message, - wireOptions.noResponse ? { ok: 1 } : (object ??= document.toObject(bsonOptions)), + options.noResponse + ? undefined + : 'moreToCome' in message && message.moreToCome + ? { ok: 1 } + : (object ??= document.toObject(bsonOptions)), started, this.description.serverConnectionId ) From 1e522639495fdb4d473ef3e3e785f1dfcd9698b3 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 9 Sep 2024 16:25:00 -0400 Subject: [PATCH 07/15] fix failing tests --- test/integration/read-write-concern/write_concern.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index b00e971312d..9d479a22718 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -13,6 +13,7 @@ import { OpMsgRequest } from '../../mongodb'; import * as mock from '../../tools/mongodb-mock/index'; +import { sleep } from '../../tools/utils'; import { filterForCommands } from '../shared'; describe('Write Concern', function () { @@ -98,6 +99,7 @@ describe('Write Concern', function () { afterEach(async function () { await db.dropDatabase(); + await sleep(1000); await client.close(); }); @@ -134,9 +136,10 @@ describe('Write Concern', function () { await col.createIndex({ b: -1 }); await col.createIndex({ a: 1, b: -1 }); + await sleep(1000); + const listIndexesResult = col.listIndexes({ batchSize: 2 }); const err = await listIndexesResult.toArray().catch(e => e); - expect(err).to.not.be.instanceOf(Error); }); @@ -165,6 +168,8 @@ describe('Write Concern', function () { { writeConcern: { w: 'majority' } } ); + await sleep(1000); + const err = await changes.next().catch(e => e); expect(err).to.not.be.instanceOf(Error); } From 7ca5e034a43522e07697915058b9928f8a364855 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 12 Sep 2024 12:02:27 -0400 Subject: [PATCH 08/15] requested changes 1 --- test/integration/read-write-concern/write_concern.test.ts | 8 +------- test/unit/commands.test.ts | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index 9d479a22718..64e656e4df4 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -13,7 +13,6 @@ import { OpMsgRequest } from '../../mongodb'; import * as mock from '../../tools/mongodb-mock/index'; -import { sleep } from '../../tools/utils'; import { filterForCommands } from '../shared'; describe('Write Concern', function () { @@ -98,8 +97,7 @@ describe('Write Concern', function () { }); afterEach(async function () { - await db.dropDatabase(); - await sleep(1000); + await db.dropDatabase({ writeConcern: { w: 'majority' } }); await client.close(); }); @@ -136,8 +134,6 @@ describe('Write Concern', function () { await col.createIndex({ b: -1 }); await col.createIndex({ a: 1, b: -1 }); - await sleep(1000); - const listIndexesResult = col.listIndexes({ batchSize: 2 }); const err = await listIndexesResult.toArray().catch(e => e); expect(err).to.not.be.instanceOf(Error); @@ -168,8 +164,6 @@ describe('Write Concern', function () { { writeConcern: { w: 'majority' } } ); - await sleep(1000); - const err = await changes.next().catch(e => e); expect(err).to.not.be.instanceOf(Error); } diff --git a/test/unit/commands.test.ts b/test/unit/commands.test.ts index 2b2cf5f58b4..3f601c678c0 100644 --- a/test/unit/commands.test.ts +++ b/test/unit/commands.test.ts @@ -111,7 +111,7 @@ describe('class OpCompressedRequest', () => { }); describe('OpMsgRequest', () => { - describe('fire-and-forget', () => { + describe('#constructor', () => { context('when writeConcern = 0', () => { it('moreToCome is set to true', async () => { const request = new OpMsgRequest('db', { a: 1, writeConcern: { w: 0 } }, {}); From 8243f9953e3a220a917790c23546087dfe9caeb2 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 12 Sep 2024 17:31:59 -0400 Subject: [PATCH 09/15] remove moreToCome as an option on the request - only on the reply --- src/cmap/commands.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index a7554ff8819..02f7fa0d7e9 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -50,7 +50,6 @@ export interface OpQueryOptions extends CommandOptions { secondaryOk?: boolean; requestId?: number; - moreToCome?: boolean; exhaustAllowed?: boolean; } @@ -412,7 +411,6 @@ export interface OpMsgOptions { ignoreUndefined: boolean; checkKeys: boolean; maxBsonSize: number; - moreToCome: boolean; exhaustAllowed: boolean; readPreference: ReadPreference; } @@ -465,7 +463,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; + this.moreToCome = command.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } From 7c607fd8356190e222aedba6be32edd40e703059 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 12 Sep 2024 17:46:37 -0400 Subject: [PATCH 10/15] add check to remove wordiness --- src/cmap/commands.ts | 2 ++ src/cmap/connection.ts | 4 ++-- test/integration/node-specific/mongo_client.test.ts | 2 +- test/integration/read-write-concern/write_concern.test.ts | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index 02f7fa0d7e9..a613447a06f 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -73,6 +73,8 @@ export class OpQueryRequest { awaitData: boolean; exhaust: boolean; partial: boolean; + /** moreToCome is an OP_MSG only concept */ + moreToCome = false; constructor( public databaseName: string, diff --git a/src/cmap/connection.ts b/src/cmap/connection.ts index c8b51528704..986cce46b6e 100644 --- a/src/cmap/connection.ts +++ b/src/cmap/connection.ts @@ -439,7 +439,7 @@ export class Connection extends TypedEventEmitter { zlibCompressionLevel: this.description.zlibCompressionLevel }); - if (options.noResponse || ('moreToCome' in message && message.moreToCome)) { + if (options.noResponse || message.moreToCome) { yield MongoDBResponse.empty; return; } @@ -529,7 +529,7 @@ export class Connection extends TypedEventEmitter { message, options.noResponse ? undefined - : 'moreToCome' in message && message.moreToCome + : message.moreToCome ? { ok: 1 } : (object ??= document.toObject(bsonOptions)), started, diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index 634516f8f76..bf94cbab7d6 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.have.property('reply', undefined); // noReponse: true + expect(endEvents[0]).to.containSubset({ reply: { ok: 1 } }); }); context('when server selection would return no servers', () => { diff --git a/test/integration/read-write-concern/write_concern.test.ts b/test/integration/read-write-concern/write_concern.test.ts index 64e656e4df4..9db7269b89f 100644 --- a/test/integration/read-write-concern/write_concern.test.ts +++ b/test/integration/read-write-concern/write_concern.test.ts @@ -136,6 +136,7 @@ describe('Write Concern', function () { const listIndexesResult = col.listIndexes({ batchSize: 2 }); const err = await listIndexesResult.toArray().catch(e => e); + expect(err).to.not.be.instanceOf(Error); }); From 8b59ecd10c96d10128003bca574952a4b0c8a200 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 10:44:20 -0400 Subject: [PATCH 11/15] remove extraneous change --- test/integration/node-specific/mongo_client.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index bf94cbab7d6..7ef0ecfc321 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.containSubset({ reply: { ok: 1 } }); + expect(endEvents[0]).to.property('reply', undefined); }); context('when server selection would return no servers', () => { From 6422402188bb3fd8573a96c19dda0027dacbcdae Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 10:57:11 -0400 Subject: [PATCH 12/15] deprecate noResponse --- src/operations/command.ts | 1 + src/operations/run_command.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/operations/command.ts b/src/operations/command.ts index 94ccc6ceafe..51a6f647e93 100644 --- a/src/operations/command.ts +++ b/src/operations/command.ts @@ -55,6 +55,7 @@ export interface CommandOperationOptions // Admin command overrides. dbName?: string; authdb?: string; + /** @deprecated Will be removed in the next major version. Set writeConcern.w to 0 instead. */ noResponse?: boolean; } diff --git a/src/operations/run_command.ts b/src/operations/run_command.ts index ad7d02c044f..7c8abb76333 100644 --- a/src/operations/run_command.ts +++ b/src/operations/run_command.ts @@ -51,6 +51,7 @@ export class RunAdminCommandOperation extends AbstractOperation constructor( public command: Document, public override options: RunCommandOptions & { + /** @deprecated Will be removed in the next major version, and replaced with an option to set writeConcern.w to 0 */ noResponse?: boolean; bypassPinningCheck?: boolean; } From ee93834b08ca7556b30125cce8399b11b35d9dd8 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 15:59:46 -0400 Subject: [PATCH 13/15] add moreToCome back on the request --- src/cmap/commands.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index a613447a06f..1cc074b3b1c 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -50,6 +50,7 @@ export interface OpQueryOptions extends CommandOptions { secondaryOk?: boolean; requestId?: number; + moreToCome?: boolean; exhaustAllowed?: boolean; } @@ -408,12 +409,21 @@ const OPTS_EXHAUST_ALLOWED = 1 << 16; /** @internal */ export interface OpMsgOptions { - requestId: number; - serializeFunctions: boolean; - ignoreUndefined: boolean; - checkKeys: boolean; - maxBsonSize: number; - exhaustAllowed: boolean; + socketTimeoutMS?: number; + session?: ClientSession; + numberToSkip?: number; + numberToReturn?: number; + returnFieldSelector?: Document; + pre32Limit?: number; + serializeFunctions?: boolean; + ignoreUndefined?: boolean; + maxBsonSize?: number; + checkKeys?: boolean; + secondaryOk?: boolean; + + requestId?: number; + moreToCome?: boolean; + exhaustAllowed?: boolean; readPreference: ReadPreference; } @@ -465,7 +475,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = command.writeConcern?.w === 0 || false; + this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } From 56772b7f72795e6564edd74c711014e8daea3377 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 13 Sep 2024 16:07:26 -0400 Subject: [PATCH 14/15] update deprecation comment --- src/operations/command.ts | 7 ++++++- src/operations/run_command.ts | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/operations/command.ts b/src/operations/command.ts index 51a6f647e93..8bfa111edfa 100644 --- a/src/operations/command.ts +++ b/src/operations/command.ts @@ -55,7 +55,12 @@ export interface CommandOperationOptions // Admin command overrides. dbName?: string; authdb?: string; - /** @deprecated Will be removed in the next major version. Set writeConcern.w to 0 instead. */ + /** + * @deprecated + * Will be removed in the next major version. Set writeConcern.w to 0 instead. + * + * **WARNING:** When this flag is true, it may result in indeterminate driver behavior. + */ noResponse?: boolean; } diff --git a/src/operations/run_command.ts b/src/operations/run_command.ts index 7c8abb76333..ad7d02c044f 100644 --- a/src/operations/run_command.ts +++ b/src/operations/run_command.ts @@ -51,7 +51,6 @@ export class RunAdminCommandOperation extends AbstractOperation constructor( public command: Document, public override options: RunCommandOptions & { - /** @deprecated Will be removed in the next major version, and replaced with an option to set writeConcern.w to 0 */ noResponse?: boolean; bypassPinningCheck?: boolean; } From 6104c57e71a6fc4ad202f8185cde69655af8f5cb Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Mon, 16 Sep 2024 10:51:54 -0400 Subject: [PATCH 15/15] remove noResponse deprecation - do in node-6377 lint fix --- src/cmap/commands.ts | 2 +- src/operations/command.ts | 6 ------ test/integration/node-specific/mongo_client.test.ts | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/cmap/commands.ts b/src/cmap/commands.ts index 1cc074b3b1c..73ef1f2e1f4 100644 --- a/src/cmap/commands.ts +++ b/src/cmap/commands.ts @@ -475,7 +475,7 @@ export class OpMsgRequest { // flags this.checksumPresent = false; - this.moreToCome = options.moreToCome || command.writeConcern?.w === 0 || false; + this.moreToCome = options.moreToCome ?? command.writeConcern?.w === 0; this.exhaustAllowed = typeof options.exhaustAllowed === 'boolean' ? options.exhaustAllowed : false; } diff --git a/src/operations/command.ts b/src/operations/command.ts index 8bfa111edfa..94ccc6ceafe 100644 --- a/src/operations/command.ts +++ b/src/operations/command.ts @@ -55,12 +55,6 @@ export interface CommandOperationOptions // Admin command overrides. dbName?: string; authdb?: string; - /** - * @deprecated - * Will be removed in the next major version. Set writeConcern.w to 0 instead. - * - * **WARNING:** When this flag is true, it may result in indeterminate driver behavior. - */ noResponse?: boolean; } diff --git a/test/integration/node-specific/mongo_client.test.ts b/test/integration/node-specific/mongo_client.test.ts index 7ef0ecfc321..634516f8f76 100644 --- a/test/integration/node-specific/mongo_client.test.ts +++ b/test/integration/node-specific/mongo_client.test.ts @@ -698,7 +698,7 @@ describe('class MongoClient', function () { expect(startedEvents).to.have.lengthOf(1); expect(startedEvents[0]).to.have.property('commandName', 'endSessions'); expect(endEvents).to.have.lengthOf(1); - expect(endEvents[0]).to.property('reply', undefined); + expect(endEvents[0]).to.have.property('reply', undefined); // noReponse: true }); context('when server selection would return no servers', () => {