Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(NODE-5044): Write Concern 0 Must Not Affect Read Operations (#3541) #3575

Merged
merged 4 commits into from
Feb 22, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/change_stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export type OperationTime = Timestamp;
* Options that can be passed to a ChangeStream. Note that startAfter, resumeAfter, and startAtOperationTime are all mutually exclusive, and the server will error if more than one is specified.
* @public
*/
export interface ChangeStreamOptions extends AggregateOptions {
export interface ChangeStreamOptions extends Omit<AggregateOptions, 'writeConcern'> {
/**
* Allowed values: 'updateLookup', 'whenAvailable', 'required'.
*
Expand Down Expand Up @@ -533,7 +533,14 @@ export class ChangeStream<
TChange extends Document = ChangeStreamDocument<TSchema>
> extends TypedEventEmitter<ChangeStreamEvents<TSchema, TChange>> {
pipeline: Document[];
options: ChangeStreamOptions;
/**
* @remarks WriteConcern can still be present on the options because
* we inherit options from the client/db/collection. The
* key must be present on the options in order to delete it.
* This allows typescript to delete the key but will
* not allow a writeConcern to be assigned as a property on options.
*/
options: ChangeStreamOptions & { writeConcern?: never };
parent: MongoClient | Db | Collection;
namespace: MongoDBNamespace;
type: symbol;
Expand Down Expand Up @@ -586,7 +593,8 @@ export class ChangeStream<
super();

this.pipeline = pipeline;
this.options = options;
this.options = { ...options };
delete this.options.writeConcern;
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved

if (parent instanceof Collection) {
this.type = CHANGE_DOMAIN_TYPES.COLLECTION;
Expand Down
4 changes: 3 additions & 1 deletion src/operations/aggregate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export class AggregateOperation<T = Document> extends CommandOperation<T> {
constructor(ns: MongoDBNamespace, pipeline: Document[], options?: AggregateOptions) {
super(undefined, { ...options, dbName: ns.db });

this.options = options ?? {};
this.options = { ...options };

// Covers when ns.collection is null, undefined or the empty string, use DB_AGGREGATE_COLLECTION
this.target = ns.collection || DB_AGGREGATE_COLLECTION;
Expand All @@ -65,6 +65,8 @@ export class AggregateOperation<T = Document> extends CommandOperation<T> {

if (this.hasWriteStage) {
this.trySecondaryWrite = true;
} else {
delete this.options.writeConcern;
}

if (this.explain && this.writeConcern) {
Expand Down
15 changes: 12 additions & 3 deletions src/operations/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { Aspect, defineAspects, Hint } from './operation';
* @typeParam TSchema - Unused schema definition, deprecated usage, only specify `FindOptions` with no generic
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export interface FindOptions<TSchema extends Document = Document> extends CommandOperationOptions {
export interface FindOptions<TSchema extends Document = Document>
extends Omit<CommandOperationOptions, 'writeConcern'> {
/** Sets the limit of documents returned in the query. */
limit?: number;
/** Set to sort the documents coming back from the query. Array of indexes, `[['a', 1]]` etc. */
Expand Down Expand Up @@ -66,7 +67,14 @@ export interface FindOptions<TSchema extends Document = Document> extends Comman

/** @internal */
export class FindOperation extends CommandOperation<Document> {
override options: FindOptions;
/**
* @remarks WriteConcern can still be present on the options because
* we inherit options from the client/db/collection. The
* key must be present on the options in order to delete it.
* This allows typescript to delete the key but will
* not allow a writeConcern to be assigned as a property on options.
*/
override options: FindOptions & { writeConcern?: never };
filter: Document;

constructor(
Expand All @@ -77,7 +85,8 @@ export class FindOperation extends CommandOperation<Document> {
) {
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
super(collection, options);

this.options = options;
this.options = { ...options };
delete this.options.writeConcern;
this.ns = ns;

if (typeof filter !== 'object' || Array.isArray(filter)) {
Expand Down
16 changes: 12 additions & 4 deletions src/operations/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export interface IndexDescription
}

/** @public */
export interface CreateIndexesOptions extends CommandOperationOptions {
export interface CreateIndexesOptions extends Omit<CommandOperationOptions, 'writeConcern'> {
/** Creates the index in the background, yielding whenever possible. */
background?: boolean;
/** Creates an unique index. */
Expand Down Expand Up @@ -382,20 +382,28 @@ export class DropIndexesOperation extends DropIndexOperation {
}

/** @public */
export interface ListIndexesOptions extends CommandOperationOptions {
export interface ListIndexesOptions extends Omit<CommandOperationOptions, 'writeConcern'> {
/** The batchSize for the returned command cursor or if pre 2.8 the systems batch collection */
batchSize?: number;
}

/** @internal */
export class ListIndexesOperation extends CommandOperation<Document> {
override options: ListIndexesOptions;
/**
* @remarks WriteConcern can still be present on the options because
* we inherit options from the client/db/collection. The
* key must be present on the options in order to delete it.
* This allows typescript to delete the key but will
* not allow a writeConcern to be assigned as a property on options.
*/
override options: ListIndexesOptions & { writeConcern?: never };
collectionNamespace: MongoDBNamespace;

constructor(collection: Collection, options?: ListIndexesOptions) {
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
super(collection, options);

this.options = options ?? {};
this.options = { ...options };
delete this.options.writeConcern;
this.collectionNamespace = collection.s.namespace;
}

Expand Down
14 changes: 11 additions & 3 deletions src/operations/list_collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { CommandOperation, CommandOperationOptions } from './command';
import { Aspect, defineAspects } from './operation';

/** @public */
export interface ListCollectionsOptions extends CommandOperationOptions {
export interface ListCollectionsOptions extends Omit<CommandOperationOptions, 'writeConcern'> {
/** Since 4.0: If true, will only return the collection name in the response, and will omit additional info */
nameOnly?: boolean;
/** Since 4.0: If true and nameOnly is true, allows a user without the required privilege (i.e. listCollections action on the database) to run the command when access control is enforced. */
Expand All @@ -18,7 +18,14 @@ export interface ListCollectionsOptions extends CommandOperationOptions {

/** @internal */
export class ListCollectionsOperation extends CommandOperation<string[]> {
override options: ListCollectionsOptions;
/**
* @remarks WriteConcern can still be present on the options because
* we inherit options from the client/db/collection. The
* key must be present on the options in order to delete it.
* This allows typescript to delete the key but will
* not allow a writeConcern to be assigned as a property on options.
*/
override options: ListCollectionsOptions & { writeConcern?: never };
db: Db;
filter: Document;
nameOnly: boolean;
Expand All @@ -28,7 +35,8 @@ export class ListCollectionsOperation extends CommandOperation<string[]> {
constructor(db: Db, filter: Document, options?: ListCollectionsOptions) {
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
super(db, options);

this.options = options ?? {};
this.options = { ...options };
delete this.options.writeConcern;
this.db = db;
this.filter = filter;
this.nameOnly = !!this.options.nameOnly;
Expand Down
75 changes: 0 additions & 75 deletions test/integration/read-write-concern/write_concern.test.js

This file was deleted.