Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions src/cmap/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ export interface CommandOptions extends BSONSerializeOptions {
/** Session to use for the operation */
session?: ClientSession;
documentsReturnedIn?: string;
noResponse?: boolean;
omitMaxTimeMS?: boolean;

// TODO(NODE-2802): Currently the CommandOptions take a property willRetryWrite which is a hint
Expand Down Expand Up @@ -467,7 +466,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
signal: options.signal
});

if (options.noResponse || message.moreToCome) {
if (message.moreToCome) {
yield MongoDBResponse.empty;
return;
}
Expand Down Expand Up @@ -567,11 +566,7 @@ export class Connection extends TypedEventEmitter<ConnectionEvents> {
new CommandSucceededEvent(
this,
message,
options.noResponse
? undefined
: message.moreToCome
? { ok: 1 }
: (object ??= document.toObject(bsonOptions)),
message.moreToCome ? { ok: 1 } : (object ??= document.toObject(bsonOptions)),
started,
this.description.serverConnectionId
)
Expand Down
5 changes: 0 additions & 5 deletions src/operations/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,6 @@ export interface CommandOperationOptions
// Admin command overrides.
dbName?: string;
authdb?: string;
/**
* @deprecated
* This option is deprecated and will be removed in an upcoming major version.
*/
noResponse?: boolean;

/**
* Used when the command needs to grant access to the underlying namespaces for time series collections.
Expand Down
18 changes: 10 additions & 8 deletions src/operations/end_sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import {
type Connection,
type ServerCommandOptions,
type ServerSessionId,
type TimeoutContext
type TimeoutContext,
type WriteConcern
} from '..';
import { type Document } from '../bson';
import { MongoDBResponse } from '../cmap/wire_protocol/responses';
import { CommandOperation } from '../operations/command';
import { ReadPreference } from '../read_preference';
import { MongoDBNamespace } from '../utils';
import { AbstractOperation } from './operation';
import { Aspect, defineAspects } from './operation';

export class EndSessionsOperation extends AbstractOperation<void> {
export class EndSessionsOperation extends CommandOperation<void> {
override writeConcern: WriteConcern = { w: 0 };
override ns = MongoDBNamespace.fromString('admin.$cmd');
override SERVER_COMMAND_RESPONSE_TYPE = MongoDBResponse;

Expand All @@ -22,21 +25,20 @@ export class EndSessionsOperation extends AbstractOperation<void> {
this.sessions = sessions;
}

override buildCommand(_connection: Connection, _session?: ClientSession): Document {
override buildCommandDocument(_connection: Connection, _session?: ClientSession): Document {
return {
endSessions: this.sessions
};
}

override buildOptions(timeoutContext: TimeoutContext): ServerCommandOptions {
return {
timeoutContext,
readPreference: ReadPreference.primaryPreferred,
noResponse: true
readPreference: ReadPreference.primaryPreferred
};
}

override get commandName(): string {
return 'endSessions';
}
}

defineAspects(EndSessionsOperation, Aspect.WRITE_OPERATION);
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,14 @@ describe('Connection', function () {
req.reply({ ok: 1 });
}, 800);
})
.addMessageHandler('endSessions', req => {
// TODO(NODE-6287): remove support for QP_QUERY from the mock server
// The mock server doesn't understand OP_MSG. So, MongoClient.close()'s use of the OP_MSG flag `moreToCome: true`
// on endSessions isn't relevant, and this test hangs unless we have a handler for `endSessions`.
// In practice, this isn't going to happen because we don't use OP_QUERY anywhere except for the initial
// handshake.
req.reply({ ok: 1 });
})
.addMessageHandler('hello', req => {
req.reply(Object.assign({}, mock.HELLO));
})
Expand Down
21 changes: 15 additions & 6 deletions test/integration/node-specific/mongo_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as sinon from 'sinon';

import {
type Collection,
type CommandFailedEvent,
type CommandStartedEvent,
type CommandSucceededEvent,
Db,
Expand Down Expand Up @@ -862,23 +861,33 @@ describe('class MongoClient', function () {
expect(result2).to.have.property('ok', 1);
});

it('sends endSessions with noResponse set', async () => {
it('sends endSessions with w: 0 set', async () => {
const session = client.startSession(); // make a session to be ended
await client.db('test').command({ ping: 1 }, { session });
await session.endSession();

const startedEvents: CommandStartedEvent[] = [];
const endEvents: Array<CommandFailedEvent | CommandSucceededEvent> = [];
const endEvents: Array<CommandSucceededEvent> = [];
client.on('commandStarted', event => startedEvents.push(event));
client.on('commandSucceeded', event => endEvents.push(event));
client.on('commandFailed', event => endEvents.push(event));

await client.close();

expect(startedEvents).to.have.lengthOf(1);
expect(startedEvents[0]).to.have.property('commandName', 'endSessions');
const [
{
command: { endSessions, writeConcern }
}
] = startedEvents;
expect(endSessions).to.exist;
expect(writeConcern).to.deep.equal({ w: 0 });
expect(endEvents).to.have.lengthOf(1);
expect(endEvents[0]).to.have.property('reply', undefined); // noReponse: true

const [{ reply }] = endEvents;

// when unacknowledged writes are used, the driver uses `{ ok: 1 }` as a placeholder
// `reply` in CommandSucceededEvents
expect(reply).to.deep.equal({ ok: 1 });
});

describe('when server selection would return no servers', () => {
Expand Down
23 changes: 0 additions & 23 deletions test/unit/cmap/connection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,6 @@ describe('new Connection()', function () {

before(() => mock.createServer().then(s => (server = s)));

it('supports fire-and-forget messages', async function () {
server.setMessageHandler(request => {
const doc = request.document;
if (isHello(doc)) {
request.reply(mock.HELLO);
}

// black hole all other requests
});

const options = {
...connectionOptionsDefaults,
connectionType: Connection,
hostAddress: server.hostAddress(),
authProviders: new MongoClientAuthProviders()
};

const conn = await connect(options);
const readSpy = sinon.spy(conn, 'readMany');
await conn.command(ns('$admin.cmd'), { ping: 1 }, { noResponse: true });
expect(readSpy).to.not.have.been.called;
});

it('destroys streams which time out', async function () {
server.setMessageHandler(request => {
const doc = request.document;
Expand Down