Skip to content

Commit 124cc36

Browse files
DRIVERS-1256: specify how drivers set timeouts on explain commands (#1640)
1 parent 2665a24 commit 124cc36

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

source/client-side-operations-timeout/client-side-operations-timeout.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,20 @@ check the command document for the presence of a `maxTimeMS` field.
428428

429429
See [runCommand behavior](#runcommand-behavior).
430430

431+
### Explain
432+
433+
> [!NOTE]
434+
> This portion of the specification is only relevant for drivers that provide `explain` helpers.
435+
436+
When `timeoutMS` is specified, drivers MUST provide a way to specify timeoutMS that results in maxTimeMS being set on
437+
the `explain` command. For example, Node's implementation might look like:
438+
439+
```typescript
440+
collection.find({}).explain({ timeoutMS: 1000 });
441+
// sends:
442+
{ explain: { find: ... }, maxTimeMS: <remaining timeoutMS - min rtt>}
443+
```
444+
431445
## Test Plan
432446

433447
See the [README.md](tests/README.md) in the tests directory.
@@ -651,6 +665,7 @@ timeout for each database operation. This would mimic using `timeoutMode=ITERATI
651665

652666
## Changelog
653667

668+
- 2024-09-12: Specify that explain helpers support support timeoutMS.
654669
- 2023-12-07: Migrated from reStructuredText to Markdown.
655670
- 2022-11-17: Use minimum RTT for maxTimeMS calculation instead of 90th percentile RTT.
656671
- 2022-10-05: Remove spec front matter.

source/crud/crud.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ Drivers MUST enforce timeouts for all operations per the
104104
[Client Side Operations Timeout](../client-side-operations-timeout/client-side-operations-timeout.md) specification. All
105105
operations that return cursors MUST support the timeout options documented in the
106106
[Cursors](../client-side-operations-timeout/client-side-operations-timeout.md#cursors) section of that specification.
107+
All explain helpers MUST support the timeout options documented in the
108+
[Explain Helpers](../client-side-operations-timeout/client-side-operations-timeout.md#explain) section of that
109+
specification.
107110

108111
### API
109112

@@ -178,9 +181,6 @@ interface Collection {
178181
* as it would be impossible to be forwards and backwards compatible. Let the server
179182
* handle the validation.
180183
*
181-
* Note: If $explain is specified in the modifiers, the return value is a single
182-
* document. This could cause problems for static languages using strongly typed entities.
183-
*
184184
* Note: result iteration should be backed by a cursor. Depending on the implementation,
185185
* the cursor may back the returned Iterable instance or an iterator that it produces.
186186
*
@@ -2201,6 +2201,47 @@ the [$readPreference global command argument](../message/OP_MSG.md#global-comman
22012201
[passing read preference to mongos and load balancers](../server-selection/server-selection.md#passing-read-preference-to-mongos-and-load-balancers)
22022202
(if applicable).
22032203

2204+
### Explain
2205+
2206+
> [!NOTE]
2207+
> Explain helpers are optional. Drivers that do not provide explain helpers may ignore this section.
2208+
2209+
```typescript
2210+
interface ExplainOptions {
2211+
/**
2212+
* The maximum amount of time to allow the explain to run.
2213+
*
2214+
* This option is sent only if the caller explicitly provides a value. The default is to not send a value.
2215+
*
2216+
* NOTE: This option is deprecated in favor of timeoutMS.
2217+
*/
2218+
maxTimeMS: Optional<Int64>;
2219+
}
2220+
```
2221+
2222+
Drivers MUST ensure that its helper permits users to specify a timeout (maxTimeMS or timeoutMS) for the explain command
2223+
specifically. An example, using Node, might look like:
2224+
2225+
```typescript
2226+
collection.find({ name: 'john doe' }).explain({ maxTimeMS: 1000 });
2227+
2228+
// sends:
2229+
{
2230+
explain: { find: <collection>, query: { name: 'john doe' } },
2231+
maxTimeMS: 1000
2232+
}
2233+
2234+
collection.find({ name: 'john doe' }).explain({ timeoutMS: 1000 });
2235+
2236+
// sends:
2237+
{
2238+
explain: { find: <collection>, query: { name: 'john doe' } },
2239+
maxTimeMS: <1000 - min rtt>
2240+
}
2241+
```
2242+
2243+
Drivers MUST document how users can specify options on their explain helpers.
2244+
22042245
## Test Plan
22052246

22062247
See the [README](tests/README.md) for tests.
@@ -2313,6 +2354,13 @@ api be consistent with the rest of the methods in the CRUD family of operations.
23132354
able to be used as this change is non-backwards breaking. Any driver which implemented the fluent bulk API should
23142355
deprecate it and drivers that have not built it should not do so.
23152356

2357+
Q: Should drivers offer explain helpers?\
2358+
Originally, it was determined that explain should not be exposed via
2359+
specialized APIs in drivers because it it was deemed to be an unusual use-case for a driver. We'd like users to use the
2360+
shell for this purpose. However, explain is still possible from a driver. Some drivers have historically provided
2361+
explain helpers and continue to do so. Drivers that do not offer explain helpers can run explain commands using the
2362+
runCommand API.
2363+
23162364
Q: What about explain?
23172365

23182366
Explain has been determined to be not a normal use-case for a driver. We'd like users to use the shell for this purpose.
@@ -2382,6 +2430,8 @@ aforementioned allowance in the SemVer spec.
23822430

23832431
## Changelog
23842432

2433+
- 2024-09-12: Specify that explain helpers support maxTimeMS.
2434+
23852435
- 2024-02-20: Migrated from reStructuredText to Markdown.
23862436

23872437
- 2022-10-05: Remove spec front matter and reformat changelog.

source/crud/tests/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,3 +677,19 @@ InsertOne {
677677

678678
Execute `bulkWrite` on `client` with `model`. Assert that an error (referred to as `error`) is returned. Assert that
679679
`error` is a client error containing the message: "bulkWrite does not currently support automatic encryption".
680+
681+
### 14. `explain` helpers allow users to specify `maxTimeMS`
682+
683+
Drivers that provide multiple APIs to specify explain should ensure this test is run at least once with each distinct
684+
API. For example, the Node driver runs this test with option API (`collection.find({}, { explain: ... })`) and the
685+
fluent API (`collection.find({}).explain(...)`).
686+
687+
Create a MongoClient with command monitoring enabled (referred to as `client`).
688+
689+
Create a collection, referred to as `collection`, with the namespace `explain-test.collection`.
690+
691+
Run an explained find on `collection`. The find will have the query predicate `{ name: 'john doe' }`. Specify a
692+
maxTimeMS value of 2000ms for the `explain`.
693+
694+
Obtain the command started event for the explain. Confirm that the top-level explain command should has a `maxTimeMS`
695+
value of `2000`.

0 commit comments

Comments
 (0)