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

feat(NODE-6520): add client side operations timeoutMS #4095

Merged
merged 35 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4789552
feat(NODE-6090): Implement CSOT logic for connection checkout and ser…
W-A-James Apr 11, 2024
1dfabeb
test(NODE-6120): Implement Unified test runner changes for CSOT (#4121)
W-A-James Jun 10, 2024
a791df7
refactor(NODE-6187): refactor to use TimeoutContext abstraction (#4131)
W-A-James Jun 21, 2024
e7d4494
refactor(NODE-6230): executeOperation to use iterative retry mechanis…
nbbeeken Jul 22, 2024
3c8e63e
feat(NODE-5682): set maxTimeMS on commands and preempt I/O (#4174)
nbbeeken Jul 26, 2024
c8c6dee
feat(NODE-6231): Add CSOT behaviour for retryable reads and writes (#…
W-A-James Aug 1, 2024
79dc352
feat(NODE-6312): add error transformation for server timeouts (#4192)
nbbeeken Aug 12, 2024
5ed0b98
feat(NODE-6313): add CSOT support to sessions and transactions (#4199)
nbbeeken Sep 9, 2024
9292e1d
feat(NODE-6304): add CSOT support for non-tailable cursors (#4195)
W-A-James Sep 12, 2024
30adbd3
fix(NODE-6374): MongoOperationTimeoutError inherits MongoRuntimeError…
nbbeeken Sep 12, 2024
a089622
test: remove empty skipped context blocks (#4238)
W-A-James Sep 12, 2024
9b7f952
feat(NODE-5844): add iscryptd to ServerDescription (#4239)
nbbeeken Sep 17, 2024
0eb0b87
chore: allow clientBulkWrite to use TimeoutContext (#4251)
W-A-James Sep 25, 2024
0559d85
feat(NODE-6274): add CSOT support to bulkWrite (#4250)
nbbeeken Oct 2, 2024
0623dc3
feat(NODE-6275): Add CSOT support to GridFS (#4246)
W-A-James Oct 4, 2024
b39b5d4
refactor(NODE-6411): AbstractCursor accepts an external timeout conte…
baileympearson Oct 4, 2024
20e43a1
feat(NODE-6305): Add CSOT support to tailable cursors (#4218)
W-A-James Oct 7, 2024
2fb1140
feat(NODE-6389): add support for timeoutMS in StateMachine.execute() …
aditi-khare-mongoDB Oct 7, 2024
c011108
fix(NODE-6412): read stale response from previously timed out connect…
nbbeeken Oct 11, 2024
bea3cf3
feat(NODE-6403): add CSOT support to client bulk write (#4261)
baileympearson Oct 14, 2024
b03b3f3
chore: fix a few flaky CSOT tests (#4278)
baileympearson Oct 17, 2024
583024c
feat(NODE-6421): add support for timeoutMS to explain helpers (#4268)
baileympearson Oct 21, 2024
c4b4600
docs(NODE-6223): timeoutMS does not govern auto-connect (#4280)
nbbeeken Oct 23, 2024
18b3d31
chore: fix resource management tests (#4293)
baileympearson Oct 25, 2024
3054eaf
feat(NODE-6390): Add timeoutMS support to auto encryption (#4265)
aditi-khare-mongoDB Oct 25, 2024
bdaf4cf
feat(NODE-6446): deprecate legacy timeout options (#4279)
W-A-James Oct 25, 2024
b160d0d
feat(NODE-6392): add timeoutMS support to ClientEncryption helpers pa…
nbbeeken Oct 28, 2024
858c7cf
feat(NODE-6387): Add CSOT support to change streams (#4256)
W-A-James Oct 29, 2024
4787342
feat(NODE-6391): Add timeoutMS support to explicit encryption (#4269)
aditi-khare-mongoDB Oct 29, 2024
c619368
fix(NODE-6454): use timeoutcontext for state machine execute() cursor…
baileympearson Oct 31, 2024
0f37094
docs(NODE-6457): Document CSOT change stream behaviour (#4301)
W-A-James Oct 31, 2024
3932a03
docs(NODE-6458): document CSOT for explicit encryption (#4302)
baileympearson Nov 1, 2024
22d8c17
docs(NODE-6456): document CSOT pt 1 (#4292)
W-A-James Nov 1, 2024
03e42d4
chore(NODE-6493): CSOT clean ups and sync runCursorCommand test (#4309)
nbbeeken Nov 4, 2024
5d497c5
docs(NODE-6516): add documentation for MongoOperationTimeoutError and…
nbbeeken Nov 6, 2024
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
3 changes: 3 additions & 0 deletions .evergreen/run-resource-management-feature-integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

source $DRIVERS_TOOLS/.evergreen/init-node-and-npm-env.sh

echo "node: $(node --version)"
echo "npm: $(npm --version)"

echo "Building driver..."
npm pack
echo "Building driver...finished."
Expand Down
8 changes: 7 additions & 1 deletion etc/notes/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Children of `MongoError` include:
### `MongoDriverError`

This class represents errors which originate in the driver itself or when the user incorrectly uses the driver. This class should **never** be directly instantiated.
Its children are the main classes of errors that most users will interact with: [**`MongoAPIError`**](#MongoAPIError) and [**`MongoRuntimeError`**](#MongoRuntimeError).
Its children are the main classes of errors that most users will interact with: [**`MongoAPIError`**](#MongoAPIError), [**`MongoRuntimeError`**](#MongoRuntimeError) and [**`MongoOperationTimeoutError`**](#MongoOperationTimeoutError).

### `MongoAPIError`

Expand Down Expand Up @@ -109,6 +109,12 @@ This class should **never** be directly instantiated.
| **MongoGridFSChunkError** | Thrown when a malformed or invalid chunk is encountered when reading from a GridFS Stream. |
| **MongoUnexpectedServerResponseError** | Thrown when the driver receives a **parsable** response it did not expect from the server. |

### `MongoOperationTimeoutError`

The `MongoOperationTimeoutError` class represents an error that occurs when an operation could not be completed within the specified `timeoutMS`.
It is generated by the driver in support of the "client side operation timeout" feature and inherits from `MongoDriverError`.
When `timeoutMS` is enabled `MongoServerErrors` relating to `MaxTimeExpired` errors will be converted to `MongoOperationTimeoutError`.

### MongoUnexpectedServerResponseError

Intended for the scenario where the MongoDB returns an unexpected response in relation to some state the driver is in.
Expand Down
82 changes: 41 additions & 41 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
"mocha": "^10.4.0",
"mocha-sinon": "^2.1.2",
"mongodb-client-encryption": "^6.1.0",
"mongodb-legacy": "^6.1.0",
"mongodb-legacy": "^6.1.3",
"nyc": "^15.1.0",
"prettier": "^3.3.3",
"semver": "^7.6.3",
Expand Down
8 changes: 6 additions & 2 deletions src/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ export class Admin {
new RunAdminCommandOperation(command, {
...resolveBSONOptions(options),
session: options?.session,
readPreference: options?.readPreference
readPreference: options?.readPreference,
timeoutMS: options?.timeoutMS ?? this.s.db.timeoutMS
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
})
);
}
Expand Down Expand Up @@ -154,7 +155,10 @@ export class Admin {
* @param options - Optional settings for the command
*/
async listDatabases(options?: ListDatabasesOptions): Promise<ListDatabasesResult> {
return await executeOperation(this.s.db.client, new ListDatabasesOperation(this.s.db, options));
return await executeOperation(
this.s.db.client,
new ListDatabasesOperation(this.s.db, { timeoutMS: this.s.db.timeoutMS, ...options })
);
}

/**
Expand Down
22 changes: 17 additions & 5 deletions src/bulk/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { makeUpdateStatement, UpdateOperation, type UpdateStatement } from '../o
import type { Server } from '../sdam/server';
import type { Topology } from '../sdam/topology';
import type { ClientSession } from '../sessions';
import { type TimeoutContext } from '../timeout';
import {
applyRetryableWrites,
getTopology,
Expand Down Expand Up @@ -500,7 +501,7 @@ export function mergeBatchResults(

async function executeCommands(
bulkOperation: BulkOperationBase,
options: BulkWriteOptions
options: BulkWriteOptions & { timeoutContext?: TimeoutContext | null }
): Promise<BulkWriteResult> {
if (bulkOperation.s.batches.length === 0) {
return new BulkWriteResult(bulkOperation.s.bulkResult, bulkOperation.isOrdered);
Expand Down Expand Up @@ -551,7 +552,11 @@ async function executeCommands(
let thrownError = null;
let result;
try {
result = await executeOperation(bulkOperation.s.collection.client, operation);
result = await executeOperation(
bulkOperation.s.collection.client,
operation,
finalOptions.timeoutContext
);
} catch (error) {
thrownError = error;
}
Expand Down Expand Up @@ -842,6 +847,9 @@ export interface BulkWriteOptions extends CommandOperationOptions {
forceServerObjectId?: boolean;
/** Map of parameter names and values that can be accessed using $$var (requires MongoDB 5.0). */
let?: Document;

/** @internal */
timeoutContext?: TimeoutContext;
}

/**
Expand All @@ -862,15 +870,19 @@ export class BulkWriteShimOperation extends AbstractOperation {
return 'bulkWrite' as const;
}

async execute(_server: Server, session: ClientSession | undefined): Promise<any> {
async execute(
_server: Server,
session: ClientSession | undefined,
timeoutContext: TimeoutContext
): Promise<any> {
if (this.options.session == null) {
// An implicit session could have been created by 'executeOperation'
// So if we stick it on finalOptions here, each bulk operation
// will use this same session, it'll be passed in the same way
// an explicit session would be
this.options.session = session;
}
return await executeCommands(this.bulkOperation, this.options);
return await executeCommands(this.bulkOperation, { ...this.options, timeoutContext });
}
}

Expand Down Expand Up @@ -1199,7 +1211,7 @@ export abstract class BulkOperationBase {
const finalOptions = { ...this.s.options, ...options };
const operation = new BulkWriteShimOperation(this, finalOptions);

return await executeOperation(this.s.collection.client, operation);
return await executeOperation(this.s.collection.client, operation, finalOptions.timeoutContext);
}

/**
Expand Down
Loading