Skip to content

Commit

Permalink
feat(NODE-5274): deprecate write concern options
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed Jul 3, 2023
1 parent 1c84f82 commit aeda89a
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/operations/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export abstract class CommandOperation<T> extends AbstractOperation<T> {
}

if (this.writeConcern && this.hasAspect(Aspect.WRITE_OPERATION) && !inTransaction) {
Object.assign(cmd, { writeConcern: this.writeConcern });
WriteConcern.apply(cmd, this.writeConcern);
}

if (
Expand Down
79 changes: 63 additions & 16 deletions src/write_concern.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Document } from "bson";

/** @public */
export type W = number | 'majority';

Expand All @@ -17,16 +19,36 @@ export interface WriteConcernSettings {
journal?: boolean;

// legacy options
/** The journal write concern */
/**
* The journal write concern.
* @deprecated Will be removed in the next major version. Please use the journal option.
*/
j?: boolean;
/** The write concern timeout */
/**
* The write concern timeout.
* @deprecated Will be removed in the next major version. Please use the wtimeoutMS option.
*/
wtimeout?: number;
/** The file sync write concern */
/**
* The file sync write concern.
* @deprecated Will be removed in the next major version. Please use the journal option.
*/
fsync?: boolean | 1;
}

export const WRITE_CONCERN_KEYS = ['w', 'wtimeout', 'j', 'journal', 'fsync'];

interface CommandWriteConcernOptions {
/** The write concern */
w?: W;
/** The journal write concern. */
j?: boolean;
/** The write concern timeout. */
wtimeout?: number;
/** The file sync write concern. */
fsync?: boolean | 1;
}

/**
* A MongoDB WriteConcern, which describes the level of acknowledgement
* requested from MongoDB for write operations.
Expand All @@ -35,41 +57,66 @@ export const WRITE_CONCERN_KEYS = ['w', 'wtimeout', 'j', 'journal', 'fsync'];
* @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. */
w?: W;
/** specify a time limit to prevent write operations from blocking indefinitely */
/** Request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags. */
readonly w?: W;
/** Request acknowledgment that the write operation has been written to the on-disk journal */
readonly journal?: boolean;
/** Specify a time limit to prevent write operations from blocking indefinitely */
readonly wtimeoutMS?: number;
/**
* Specify a time limit to prevent write operations from blocking indefinitely.
* @deprecated Will be removed in the next major version. Please use wtimeoutMS.
*/
wtimeout?: number;
/** request acknowledgment that the write operation has been written to the on-disk journal */
/**
* Request acknowledgment that the write operation has been written to the on-disk journal.
* @deprecated Will be removed in the next major version. Please use journal.
*/
j?: boolean;
/** equivalent to the j option */
/**
* Equivalent to the j option.
* @deprecated Will be removed in the next major version. Please use journal.
*/
fsync?: boolean | 1;

/**
* Constructs a WriteConcern from the write concern properties.
* @param w - request acknowledgment that the write operation has propagated to a specified number of mongod instances or to mongod instances with specified tags.
* @param wtimeout - specify a time limit to prevent write operations from blocking indefinitely
* @param j - request acknowledgment that the write operation has been written to the on-disk journal
* @param wtimeoutMS - specify a time limit to prevent write operations from blocking indefinitely
* @param journal - request acknowledgment that the write operation has been written to the on-disk journal
* @param fsync - equivalent to the j option
*/
constructor(w?: W, wtimeout?: number, j?: boolean, fsync?: boolean | 1) {
constructor(w?: W, wtimeoutMS?: number, journal?: boolean, fsync?: boolean | 1) {
if (w != null) {
if (!Number.isNaN(Number(w))) {
this.w = Number(w);
} else {
this.w = w;
}
}
if (wtimeout != null) {
this.wtimeout = wtimeout;
if (wtimeoutMS != null) {
this.wtimeoutMS = this.wtimeout = wtimeoutMS;
}
if (j != null) {
this.j = j;
if (journal != null) {
this.journal = this.j = journal;
}
if (fsync != null) {
this.fsync = fsync;
this.journal = this.j = fsync ? true : false;
}
}

/**
* Apply a write concern to a command document.
*/
static apply(command: Document, writeConcern: WriteConcern): Document {
const wc: CommandWriteConcernOptions = {};
// The write concern document sent to the server has w/wtimeout/j fields.
if (writeConcern.w != null) wc.w = writeConcern.w;
if (writeConcern.wtimeoutMS != null) wc.wtimeout = writeConcern.wtimeoutMS;
if (writeConcern.journal != null) wc.j = writeConcern.j;
return Object.assign(command, { writeConcern: wc });
}

/** Construct a WriteConcern given an options object. */
static fromOptions(
options?: WriteConcernOptions | WriteConcern | W,
Expand Down
106 changes: 106 additions & 0 deletions test/unit/write_concern.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { expect } from 'chai';

import { WriteConcern } from '../mongodb';

describe('WriteConcern', function () {
describe('#constructor', function () {
context('when w is provided', function () {
const writeConcern = new WriteConcern(1);

it('sets the w property', function () {
expect(writeConcern.w).to.equal(1);
});
});

context('when wtimeoutMS is provided', function () {
const writeConcern = new WriteConcern(1, 50);

it('sets the wtimeoutMS property', function () {
expect(writeConcern.wtimeoutMS).to.equal(50);
});

it('sets the wtimeout property', function () {
expect(writeConcern.wtimeout).to.equal(50);
});
});

context('when journal is provided', function () {
const writeConcern = new WriteConcern(1, 50, true);

it('sets the journal property', function () {
expect(writeConcern.journal).to.be.true;
});

it('sets the j property', function () {
expect(writeConcern.j).to.be.true;
});
});

context('when fsync is provided', function () {
const writeConcern = new WriteConcern(1, 50, false, true);

it('sets the journal property', function () {
expect(writeConcern.journal).to.be.true;
});

it('sets the j property', function () {
expect(writeConcern.j).to.be.true;
});
});
});

describe('.apply', function () {
context('when no options are set', function () {
const document = {};
const writeConcern = new WriteConcern();

it('returns an empty write concern', function () {
expect(WriteConcern.apply(document, writeConcern)).to.deep.equal({ writeConcern: {} });
});
});

context('when w is in the write concern', function () {
const document = {};
const writeConcern = new WriteConcern(2);

it('adds w to the write concern document', function () {
expect(WriteConcern.apply(document, writeConcern)).to.deep.equal({
writeConcern: { w: 2 }
});
});
});

context('when wtimeoutMS is in the write concern', function () {
const document = {};
const writeConcern = new WriteConcern(2, 30);

it('adds wtimeout to the write concern document', function () {
expect(WriteConcern.apply(document, writeConcern)).to.deep.equal({
writeConcern: { w: 2, wtimeout: 30 }
});
});
});

context('when journal is in the write concern', function () {
const document = {};
const writeConcern = new WriteConcern(2, 30, true);

it('adds j to the write concern document', function () {
expect(WriteConcern.apply(document, writeConcern)).to.deep.equal({
writeConcern: { w: 2, wtimeout: 30, j: true }
});
});
});

context('when fsync is in the write concern', function () {
const document = {};
const writeConcern = new WriteConcern(2, 30, true, false);

it('overrites j to the write concern document', function () {
expect(WriteConcern.apply(document, writeConcern)).to.deep.equal({
writeConcern: { w: 2, wtimeout: 30, j: false }
});
});
});
});
});

0 comments on commit aeda89a

Please sign in to comment.