mongodb 7.1.1 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/lib/bson.js +26 -5
- package/lib/bson.js.map +1 -1
- package/lib/change_stream.js +4 -0
- package/lib/change_stream.js.map +1 -1
- package/lib/client-side-encryption/auto_encrypter.js +19 -10
- package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
- package/lib/client-side-encryption/client_encryption.js +1 -3
- package/lib/client-side-encryption/client_encryption.js.map +1 -1
- package/lib/cmap/auth/aws4.js +4 -4
- package/lib/cmap/auth/aws4.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +3 -6
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +3 -2
- package/lib/cmap/auth/mongodb_aws.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js +3 -3
- package/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js +3 -3
- package/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +3 -3
- package/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js +3 -3
- package/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js.map +1 -1
- package/lib/cmap/auth/mongodb_oidc.js +4 -4
- package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
- package/lib/cmap/auth/plain.js +1 -1
- package/lib/cmap/auth/plain.js.map +1 -1
- package/lib/cmap/auth/scram.js +53 -40
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/commands.js +46 -39
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +1 -0
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +5 -2
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/handshake/client_metadata.js +3 -4
- package/lib/cmap/handshake/client_metadata.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +8 -7
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/on_data.js.map +1 -1
- package/lib/cmap/wire_protocol/on_demand/document.js +9 -9
- package/lib/cmap/wire_protocol/on_demand/document.js.map +1 -1
- package/lib/connection_string.js +21 -5
- package/lib/connection_string.js.map +1 -1
- package/lib/gridfs/download.js +2 -1
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/upload.js +7 -7
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/mongo_client.js.map +1 -1
- package/lib/operations/execute_operation.js +114 -41
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/operation.js +1 -0
- package/lib/operations/operation.js.map +1 -1
- package/lib/runtime_adapters.js +32 -0
- package/lib/runtime_adapters.js.map +1 -0
- package/lib/sdam/srv_polling.js +1 -1
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +4 -2
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sessions.js +124 -79
- package/lib/sessions.js.map +1 -1
- package/lib/utils.js +10 -33
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +45 -2
- package/package.json +30 -21
- package/src/bson.ts +28 -5
- package/src/change_stream.ts +5 -0
- package/src/client-side-encryption/auto_encrypter.ts +17 -11
- package/src/client-side-encryption/client_encryption.ts +1 -3
- package/src/cmap/auth/auth_provider.ts +1 -1
- package/src/cmap/auth/aws4.ts +5 -5
- package/src/cmap/auth/gssapi.ts +9 -6
- package/src/cmap/auth/mongodb_aws.ts +2 -2
- package/src/cmap/auth/mongodb_oidc/azure_machine_workflow.ts +1 -1
- package/src/cmap/auth/mongodb_oidc/gcp_machine_workflow.ts +1 -1
- package/src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts +1 -1
- package/src/cmap/auth/mongodb_oidc/token_machine_workflow.ts +1 -1
- package/src/cmap/auth/mongodb_oidc.ts +4 -4
- package/src/cmap/auth/plain.ts +2 -2
- package/src/cmap/auth/scram.ts +82 -55
- package/src/cmap/commands.ts +70 -51
- package/src/cmap/connect.ts +2 -0
- package/src/cmap/connection.ts +11 -4
- package/src/cmap/handshake/client_metadata.ts +6 -6
- package/src/cmap/wire_protocol/compression.ts +18 -14
- package/src/cmap/wire_protocol/on_data.ts +5 -5
- package/src/cmap/wire_protocol/on_demand/document.ts +12 -14
- package/src/connection_string.ts +26 -8
- package/src/deps.ts +4 -4
- package/src/gridfs/download.ts +2 -2
- package/src/gridfs/upload.ts +13 -12
- package/src/index.ts +1 -0
- package/src/mongo_client.ts +24 -0
- package/src/operations/client_bulk_write/command_builder.ts +1 -1
- package/src/operations/execute_operation.ts +146 -45
- package/src/operations/operation.ts +8 -0
- package/src/runtime_adapters.ts +64 -0
- package/src/sdam/srv_polling.ts +1 -1
- package/src/sdam/topology.ts +10 -7
- package/src/sessions.ts +140 -96
- package/src/utils.ts +21 -40
- package/tsconfig.json +1 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { setTimeout } from 'timers/promises';
|
|
2
|
+
|
|
1
3
|
import { MIN_SUPPORTED_SNAPSHOT_READS_WIRE_VERSION } from '../cmap/wire_protocol/constants';
|
|
2
4
|
import {
|
|
3
5
|
isRetryableReadError,
|
|
@@ -17,6 +19,7 @@ import {
|
|
|
17
19
|
} from '../error';
|
|
18
20
|
import type { MongoClient } from '../mongo_client';
|
|
19
21
|
import { ReadPreference } from '../read_preference';
|
|
22
|
+
import { TopologyType } from '../sdam/common';
|
|
20
23
|
import {
|
|
21
24
|
DeprioritizedServers,
|
|
22
25
|
sameServerSelector,
|
|
@@ -29,6 +32,7 @@ import { TimeoutContext } from '../timeout';
|
|
|
29
32
|
import { abortable, maxWireVersion, supportsRetryableWrites } from '../utils';
|
|
30
33
|
import { AggregateOperation } from './aggregate';
|
|
31
34
|
import { AbstractOperation, Aspect } from './operation';
|
|
35
|
+
import { RunCommandOperation } from './run_command';
|
|
32
36
|
|
|
33
37
|
const MMAPv1_RETRY_WRITES_ERROR_CODE = MONGODB_ERROR_CODES.IllegalOperation;
|
|
34
38
|
const MMAPv1_RETRY_WRITES_ERROR_MESSAGE =
|
|
@@ -50,7 +54,7 @@ type ResultTypeFromOperation<TOperation extends AbstractOperation> = ReturnType<
|
|
|
50
54
|
* The expectation is that this function:
|
|
51
55
|
* - Connects the MongoClient if it has not already been connected, see {@link autoConnect}
|
|
52
56
|
* - Creates a session if none is provided and cleans up the session it creates
|
|
53
|
-
* - Tries an operation and retries under certain conditions, see {@link
|
|
57
|
+
* - Tries an operation and retries under certain conditions, see {@link executeOperationWithRetries}
|
|
54
58
|
*
|
|
55
59
|
* @typeParam T - The operation's type
|
|
56
60
|
* @typeParam TResult - The type of the operation's result, calculated from T
|
|
@@ -120,7 +124,7 @@ export async function executeOperation<
|
|
|
120
124
|
});
|
|
121
125
|
|
|
122
126
|
try {
|
|
123
|
-
return await
|
|
127
|
+
return await executeOperationWithRetries(operation, {
|
|
124
128
|
topology,
|
|
125
129
|
timeoutContext,
|
|
126
130
|
session,
|
|
@@ -165,6 +169,10 @@ type RetryOptions = {
|
|
|
165
169
|
topology: Topology;
|
|
166
170
|
timeoutContext: TimeoutContext;
|
|
167
171
|
};
|
|
172
|
+
/** @internal The base backoff duration in milliseconds */
|
|
173
|
+
const BASE_BACKOFF_MS = 100;
|
|
174
|
+
/** @internal The maximum backoff duration in milliseconds */
|
|
175
|
+
const MAX_BACKOFF_MS = 10_000;
|
|
168
176
|
|
|
169
177
|
/**
|
|
170
178
|
* Executes an operation and retries as appropriate
|
|
@@ -183,8 +191,11 @@ type RetryOptions = {
|
|
|
183
191
|
* @typeParam TResult - The type of the operation's result, calculated from T
|
|
184
192
|
*
|
|
185
193
|
* @param operation - The operation to execute
|
|
186
|
-
|
|
187
|
-
async function
|
|
194
|
+
*/
|
|
195
|
+
async function executeOperationWithRetries<
|
|
196
|
+
T extends AbstractOperation,
|
|
197
|
+
TResult = ResultTypeFromOperation<T>
|
|
198
|
+
>(
|
|
188
199
|
operation: T,
|
|
189
200
|
{ topology, timeoutContext, session, readPreference }: RetryOptions
|
|
190
201
|
): Promise<TResult> {
|
|
@@ -233,33 +244,70 @@ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFro
|
|
|
233
244
|
session.incrementTransactionNumber();
|
|
234
245
|
}
|
|
235
246
|
|
|
236
|
-
const maxTries = willRetry ? (timeoutContext.csotEnabled() ? Infinity : 2) : 1;
|
|
237
|
-
let previousOperationError: MongoError | undefined;
|
|
238
247
|
const deprioritizedServers = new DeprioritizedServers();
|
|
239
248
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
249
|
+
let maxAttempts =
|
|
250
|
+
typeof operation.maxAttempts === 'number'
|
|
251
|
+
? operation.maxAttempts
|
|
252
|
+
: willRetry
|
|
253
|
+
? timeoutContext.csotEnabled()
|
|
254
|
+
? Infinity
|
|
255
|
+
: 2
|
|
256
|
+
: 1;
|
|
257
|
+
|
|
258
|
+
let error: MongoError | null = null;
|
|
259
|
+
|
|
260
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
261
|
+
operation.attemptsMade = attempt + 1;
|
|
262
|
+
operation.server = server;
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
try {
|
|
266
|
+
const result = await server.command(operation, timeoutContext);
|
|
267
|
+
return operation.handleOk(result);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
return operation.handleError(error);
|
|
270
|
+
}
|
|
271
|
+
} catch (operationError) {
|
|
272
|
+
// Should never happen but if it does - propagate the error.
|
|
273
|
+
if (!(operationError instanceof MongoError)) throw operationError;
|
|
274
|
+
|
|
275
|
+
// Preserve the original error once a write has been performed.
|
|
276
|
+
// Only update to the latest error if no writes were performed.
|
|
277
|
+
if (error == null) {
|
|
278
|
+
error = operationError;
|
|
279
|
+
} else {
|
|
280
|
+
if (!operationError.hasErrorLabel(MongoErrorLabel.NoWritesPerformed)) {
|
|
281
|
+
error = operationError;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Reset timeouts
|
|
286
|
+
timeoutContext.clear();
|
|
287
|
+
|
|
288
|
+
if (hasWriteAspect && operationError.code === MMAPv1_RETRY_WRITES_ERROR_CODE) {
|
|
243
289
|
throw new MongoServerError({
|
|
244
290
|
message: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
|
|
245
291
|
errmsg: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
|
|
246
|
-
originalError:
|
|
292
|
+
originalError: operationError
|
|
247
293
|
});
|
|
248
294
|
}
|
|
249
295
|
|
|
250
|
-
if (operation
|
|
251
|
-
throw
|
|
296
|
+
if (!canRetry(operation, operationError)) {
|
|
297
|
+
throw error;
|
|
252
298
|
}
|
|
253
299
|
|
|
254
|
-
if (
|
|
255
|
-
|
|
300
|
+
if (operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError)) {
|
|
301
|
+
const maxOverloadAttempts = topology.s.options.maxAdaptiveRetries + 1;
|
|
302
|
+
maxAttempts = Math.min(maxOverloadAttempts, operation.maxAttempts ?? maxOverloadAttempts);
|
|
303
|
+
}
|
|
256
304
|
|
|
257
|
-
if (
|
|
258
|
-
throw
|
|
305
|
+
if (attempt + 1 >= maxAttempts) {
|
|
306
|
+
throw error;
|
|
259
307
|
}
|
|
260
308
|
|
|
261
309
|
if (
|
|
262
|
-
|
|
310
|
+
operationError instanceof MongoNetworkError &&
|
|
263
311
|
operation.hasAspect(Aspect.CURSOR_CREATING) &&
|
|
264
312
|
session != null &&
|
|
265
313
|
session.isPinned &&
|
|
@@ -268,6 +316,35 @@ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFro
|
|
|
268
316
|
session.unpin({ force: true, forceClear: true });
|
|
269
317
|
}
|
|
270
318
|
|
|
319
|
+
if (
|
|
320
|
+
operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError) &&
|
|
321
|
+
operation.hasAspect(Aspect.CURSOR_CREATING) &&
|
|
322
|
+
session != null &&
|
|
323
|
+
session.isPinned &&
|
|
324
|
+
!session.inTransaction()
|
|
325
|
+
) {
|
|
326
|
+
session.unpin({ force: true });
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError)) {
|
|
330
|
+
const backoffMS = Math.random() * Math.min(MAX_BACKOFF_MS, BASE_BACKOFF_MS * 2 ** attempt);
|
|
331
|
+
|
|
332
|
+
// if the backoff would exhaust the CSOT timeout, short-circuit.
|
|
333
|
+
if (timeoutContext.csotEnabled() && backoffMS > timeoutContext.remainingTimeMS) {
|
|
334
|
+
throw error;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
await setTimeout(backoffMS);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (
|
|
341
|
+
topology.description.type === TopologyType.Sharded ||
|
|
342
|
+
(operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError) &&
|
|
343
|
+
topology.s.options.enableOverloadRetargeting)
|
|
344
|
+
) {
|
|
345
|
+
deprioritizedServers.add(server.description);
|
|
346
|
+
}
|
|
347
|
+
|
|
271
348
|
server = await topology.selectServer(selector, {
|
|
272
349
|
session,
|
|
273
350
|
operationName: operation.commandName,
|
|
@@ -275,45 +352,69 @@ async function tryOperation<T extends AbstractOperation, TResult = ResultTypeFro
|
|
|
275
352
|
signal: operation.options.signal
|
|
276
353
|
});
|
|
277
354
|
|
|
278
|
-
if (
|
|
355
|
+
if (
|
|
356
|
+
hasWriteAspect &&
|
|
357
|
+
!supportsRetryableWrites(server) &&
|
|
358
|
+
!operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError)
|
|
359
|
+
) {
|
|
279
360
|
throw new MongoUnexpectedServerResponseError(
|
|
280
361
|
'Selected server does not support retryable writes'
|
|
281
362
|
);
|
|
282
363
|
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
operation.server = server;
|
|
286
364
|
|
|
287
|
-
|
|
288
|
-
//
|
|
289
|
-
if (
|
|
365
|
+
// Batched operations must reset the batch before retry,
|
|
366
|
+
// otherwise building a command will build the _next_ batch, not the current batch.
|
|
367
|
+
if (operation.hasAspect(Aspect.COMMAND_BATCHING)) {
|
|
290
368
|
operation.resetBatch();
|
|
291
369
|
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
292
372
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
373
|
+
throw (
|
|
374
|
+
error ??
|
|
375
|
+
new MongoRuntimeError(
|
|
376
|
+
'Should never happen: operation execution loop terminated but no error was recorded.'
|
|
377
|
+
)
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
function canRetry(operation: AbstractOperation, error: MongoError) {
|
|
381
|
+
// SystemOverloadedError is retryable, but must respect retryReads/retryWrites settings
|
|
382
|
+
// Check topology options directly (not operation.canRetryRead/Write) because backpressure
|
|
383
|
+
// expands retry support beyond traditional retryable reads/writes
|
|
384
|
+
// NOTE: Unlike traditional retries, backpressure retries ARE allowed inside transactions
|
|
385
|
+
if (
|
|
386
|
+
error.hasErrorLabel(MongoErrorLabel.SystemOverloadedError) &&
|
|
387
|
+
error.hasErrorLabel(MongoErrorLabel.RetryableError)
|
|
388
|
+
) {
|
|
389
|
+
// runCommand requires BOTH retryReads and retryWrites to be enabled (per spec step 2.4)
|
|
390
|
+
if (operation instanceof RunCommandOperation) {
|
|
391
|
+
return topology.s.options.retryReads && topology.s.options.retryWrites;
|
|
298
392
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (
|
|
302
|
-
|
|
303
|
-
operationError.hasErrorLabel(MongoErrorLabel.NoWritesPerformed)
|
|
304
|
-
) {
|
|
305
|
-
throw previousOperationError;
|
|
393
|
+
|
|
394
|
+
// Write-stage aggregates ($out/$merge) require retryWrites
|
|
395
|
+
if (operation instanceof AggregateOperation && operation.hasWriteStage) {
|
|
396
|
+
return topology.s.options.retryWrites;
|
|
306
397
|
}
|
|
307
|
-
deprioritizedServers.add(server.description);
|
|
308
|
-
previousOperationError = operationError;
|
|
309
398
|
|
|
310
|
-
//
|
|
311
|
-
|
|
399
|
+
// For other operations, check if retries are enabled based on operation type
|
|
400
|
+
const canRetryAsRead = hasReadAspect && topology.s.options.retryReads;
|
|
401
|
+
const canRetryAsWrite = hasWriteAspect && topology.s.options.retryWrites;
|
|
402
|
+
return canRetryAsRead || canRetryAsWrite;
|
|
312
403
|
}
|
|
313
|
-
}
|
|
314
404
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
405
|
+
// run command is only retryable if we get retryable overload errors
|
|
406
|
+
if (operation instanceof RunCommandOperation) {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// batch operations are only retryable if the batch is retryable
|
|
411
|
+
if (operation.hasAspect(Aspect.COMMAND_BATCHING)) {
|
|
412
|
+
return operation.canRetryWrite && isRetryableWriteError(error);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return (
|
|
416
|
+
(hasWriteAspect && willRetryWrite && isRetryableWriteError(error)) ||
|
|
417
|
+
(hasReadAspect && willRetryRead && isRetryableReadError(error))
|
|
418
|
+
);
|
|
419
|
+
}
|
|
319
420
|
}
|
|
@@ -66,6 +66,12 @@ export abstract class AbstractOperation<TResult = any> {
|
|
|
66
66
|
/** Specifies the time an operation will run until it throws a timeout error. */
|
|
67
67
|
timeoutMS?: number;
|
|
68
68
|
|
|
69
|
+
/** Used by commitTransaction to share the retry budget across two executeOperation calls. */
|
|
70
|
+
maxAttempts?: number;
|
|
71
|
+
|
|
72
|
+
/** Tracks how many attempts were made in the last executeOperation call. */
|
|
73
|
+
attemptsMade: number;
|
|
74
|
+
|
|
69
75
|
private _session: ClientSession | undefined;
|
|
70
76
|
|
|
71
77
|
static aspects?: Set<symbol>;
|
|
@@ -82,6 +88,8 @@ export abstract class AbstractOperation<TResult = any> {
|
|
|
82
88
|
|
|
83
89
|
this.options = options;
|
|
84
90
|
this.bypassPinningCheck = !!options.bypassPinningCheck;
|
|
91
|
+
|
|
92
|
+
this.attemptsMade = 0;
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
/** Must match the first key of the command object sent to the server.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/* eslint-disable no-restricted-imports*/
|
|
2
|
+
|
|
3
|
+
// We squash the restricted import errors here because we are using type-only imports, which
|
|
4
|
+
// do not impact the driver's actual runtime dependencies.
|
|
5
|
+
// We also allow restricted imports in this file, because we expect this file to be the only place actually importing restricted Node APIs.
|
|
6
|
+
|
|
7
|
+
import type * as os from 'os';
|
|
8
|
+
|
|
9
|
+
import { type MongoClientOptions } from './mongo_client';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @internal
|
|
13
|
+
*
|
|
14
|
+
* This propery can be set on the global object to allow the driver to require otherwise blocked modules.
|
|
15
|
+
* This is used by our test suite to allow tests to access the `os` module without allowing user code to do so.
|
|
16
|
+
*/
|
|
17
|
+
export const ALLOWED_DRIVER_REQUIRE_PROPERTY_NAME = 'allowedDriverRequire';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @public
|
|
21
|
+
* @experimental
|
|
22
|
+
*
|
|
23
|
+
* Represents the set of dependencies that the driver uses from the [Node.js OS module](https://nodejs.org/api/os.html).
|
|
24
|
+
*/
|
|
25
|
+
export type OsAdapter = Pick<typeof os, 'release' | 'platform' | 'arch' | 'type'>;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @public
|
|
29
|
+
* @experimental
|
|
30
|
+
*
|
|
31
|
+
* This type represents the set of dependencies that the driver needs from the Javascript runtime in order to function.
|
|
32
|
+
*/
|
|
33
|
+
export interface RuntimeAdapters {
|
|
34
|
+
os?: OsAdapter;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @internal
|
|
39
|
+
*
|
|
40
|
+
* Represents a complete, parsed set of runtime adapters. After options parsing, all adapters
|
|
41
|
+
* are always present (either using the user's provided adapter, or defaulting to the Node.js module).
|
|
42
|
+
*/
|
|
43
|
+
export interface Runtime {
|
|
44
|
+
os: OsAdapter;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @internal
|
|
49
|
+
*
|
|
50
|
+
* Given a MongoClientOptions, this function resolves the set of runtime options, providing Nodejs implementations if
|
|
51
|
+
* not provided by in `options`, and returns a `Runtime`.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveRuntimeAdapters(options: MongoClientOptions): Runtime {
|
|
54
|
+
(globalThis as any)[ALLOWED_DRIVER_REQUIRE_PROPERTY_NAME] = true;
|
|
55
|
+
try {
|
|
56
|
+
const runtime = {
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
58
|
+
os: options.runtimeAdapters?.os ?? require('os')
|
|
59
|
+
};
|
|
60
|
+
return runtime;
|
|
61
|
+
} finally {
|
|
62
|
+
(globalThis as any)[ALLOWED_DRIVER_REQUIRE_PROPERTY_NAME] = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
package/src/sdam/srv_polling.ts
CHANGED
|
@@ -116,7 +116,7 @@ export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {
|
|
|
116
116
|
let srvRecords;
|
|
117
117
|
|
|
118
118
|
try {
|
|
119
|
-
srvRecords = await dns.promises.
|
|
119
|
+
srvRecords = await dns.promises.resolve(this.srvAddress, 'SRV');
|
|
120
120
|
} catch {
|
|
121
121
|
this.failure();
|
|
122
122
|
return;
|
package/src/sdam/topology.ts
CHANGED
|
@@ -145,6 +145,8 @@ export interface TopologyOptions extends BSONSerializeOptions, ServerOptions {
|
|
|
145
145
|
hosts: HostAddress[];
|
|
146
146
|
retryWrites: boolean;
|
|
147
147
|
retryReads: boolean;
|
|
148
|
+
maxAdaptiveRetries: number;
|
|
149
|
+
enableOverloadRetargeting: boolean;
|
|
148
150
|
/** How long to block for server selection before throwing an error */
|
|
149
151
|
serverSelectionTimeoutMS: number;
|
|
150
152
|
/** The name of the replica set to connect to */
|
|
@@ -207,18 +209,13 @@ export type TopologyEvents = {
|
|
|
207
209
|
* @internal
|
|
208
210
|
*/
|
|
209
211
|
export class Topology extends TypedEventEmitter<TopologyEvents> {
|
|
210
|
-
/** @internal */
|
|
211
212
|
s: TopologyPrivate;
|
|
212
|
-
/** @internal */
|
|
213
213
|
waitQueue: List<ServerSelectionRequest>;
|
|
214
|
-
/** @internal */
|
|
215
214
|
hello?: Document;
|
|
216
|
-
/** @internal */
|
|
217
215
|
_type?: string;
|
|
218
216
|
|
|
219
217
|
client!: MongoClient;
|
|
220
218
|
|
|
221
|
-
/** @internal */
|
|
222
219
|
private connectionLock?: Promise<Topology>;
|
|
223
220
|
|
|
224
221
|
/** @event */
|
|
@@ -595,7 +592,11 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
|
|
|
595
592
|
)
|
|
596
593
|
);
|
|
597
594
|
}
|
|
598
|
-
|
|
595
|
+
|
|
596
|
+
if (!options.timeoutContext || options.timeoutContext.clearServerSelectionTimeout) {
|
|
597
|
+
timeout?.clear();
|
|
598
|
+
}
|
|
599
|
+
|
|
599
600
|
return transaction.server;
|
|
600
601
|
}
|
|
601
602
|
|
|
@@ -666,7 +667,9 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
|
|
|
666
667
|
throw error;
|
|
667
668
|
} finally {
|
|
668
669
|
abortListener?.[kDispose]();
|
|
669
|
-
if (options.timeoutContext
|
|
670
|
+
if (!options.timeoutContext || options.timeoutContext.clearServerSelectionTimeout) {
|
|
671
|
+
timeout?.clear();
|
|
672
|
+
}
|
|
670
673
|
}
|
|
671
674
|
}
|
|
672
675
|
/**
|