mongodb 4.0.0 → 4.1.2
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 +62 -30
- package/lib/bson.js +1 -0
- package/lib/bson.js.map +1 -1
- package/lib/bulk/common.js +53 -30
- package/lib/bulk/common.js.map +1 -1
- package/lib/bulk/ordered.js +3 -2
- package/lib/bulk/ordered.js.map +1 -1
- package/lib/bulk/unordered.js +3 -2
- package/lib/bulk/unordered.js.map +1 -1
- package/lib/change_stream.js +23 -13
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/auth/auth_provider.js +2 -1
- package/lib/cmap/auth/auth_provider.js.map +1 -1
- package/lib/cmap/auth/gssapi.js +5 -4
- package/lib/cmap/auth/gssapi.js.map +1 -1
- package/lib/cmap/auth/mongo_credentials.js +9 -5
- package/lib/cmap/auth/mongo_credentials.js.map +1 -1
- package/lib/cmap/auth/mongocr.js +2 -2
- package/lib/cmap/auth/mongocr.js.map +1 -1
- package/lib/cmap/auth/mongodb_aws.js +32 -32
- package/lib/cmap/auth/mongodb_aws.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 +15 -12
- package/lib/cmap/auth/scram.js.map +1 -1
- package/lib/cmap/auth/x509.js +2 -2
- package/lib/cmap/auth/x509.js.map +1 -1
- package/lib/cmap/command_monitoring_events.js +26 -10
- package/lib/cmap/command_monitoring_events.js.map +1 -1
- package/lib/cmap/commands.js +9 -5
- package/lib/cmap/commands.js.map +1 -1
- package/lib/cmap/connect.js +23 -9
- package/lib/cmap/connect.js.map +1 -1
- package/lib/cmap/connection.js +43 -46
- package/lib/cmap/connection.js.map +1 -1
- package/lib/cmap/connection_pool.js +113 -15
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/cmap/connection_pool_events.js +3 -1
- package/lib/cmap/connection_pool_events.js.map +1 -1
- package/lib/cmap/errors.js +3 -3
- package/lib/cmap/errors.js.map +1 -1
- package/lib/cmap/message_stream.js +1 -1
- package/lib/cmap/message_stream.js.map +1 -1
- package/lib/cmap/metrics.js +62 -0
- package/lib/cmap/metrics.js.map +1 -0
- package/lib/cmap/stream_description.js +3 -1
- package/lib/cmap/stream_description.js.map +1 -1
- package/lib/cmap/wire_protocol/compression.js +22 -9
- package/lib/cmap/wire_protocol/compression.js.map +1 -1
- package/lib/cmap/wire_protocol/shared.js +1 -1
- package/lib/cmap/wire_protocol/shared.js.map +1 -1
- package/lib/collection.js +23 -18
- package/lib/collection.js.map +1 -1
- package/lib/connection_string.js +76 -30
- package/lib/connection_string.js.map +1 -1
- package/lib/cursor/abstract_cursor.js +75 -68
- package/lib/cursor/abstract_cursor.js.map +1 -1
- package/lib/cursor/aggregation_cursor.js +47 -9
- package/lib/cursor/aggregation_cursor.js.map +1 -1
- package/lib/cursor/find_cursor.js +53 -13
- package/lib/cursor/find_cursor.js.map +1 -1
- package/lib/db.js +21 -14
- package/lib/db.js.map +1 -1
- package/lib/deps.js +16 -5
- package/lib/deps.js.map +1 -1
- package/lib/encrypter.js +5 -8
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +230 -34
- package/lib/error.js.map +1 -1
- package/lib/explain.js +2 -2
- package/lib/explain.js.map +1 -1
- package/lib/gridfs/download.js +22 -47
- package/lib/gridfs/download.js.map +1 -1
- package/lib/gridfs/index.js +4 -3
- package/lib/gridfs/index.js.map +1 -1
- package/lib/gridfs/upload.js +13 -21
- package/lib/gridfs/upload.js.map +1 -1
- package/lib/index.js +27 -2
- package/lib/index.js.map +1 -1
- package/lib/logger.js +3 -2
- package/lib/logger.js.map +1 -1
- package/lib/mongo_client.js +5 -8
- package/lib/mongo_client.js.map +1 -1
- package/lib/mongo_types.js.map +1 -1
- package/lib/operations/add_user.js +2 -3
- package/lib/operations/add_user.js.map +1 -1
- package/lib/operations/aggregate.js +12 -9
- package/lib/operations/aggregate.js.map +1 -1
- package/lib/operations/command.js +5 -7
- package/lib/operations/command.js.map +1 -1
- package/lib/operations/common_functions.js +1 -1
- package/lib/operations/common_functions.js.map +1 -1
- package/lib/operations/connect.js +3 -2
- package/lib/operations/connect.js.map +1 -1
- package/lib/operations/count.js +1 -1
- package/lib/operations/count.js.map +1 -1
- package/lib/operations/count_documents.js +1 -1
- package/lib/operations/count_documents.js.map +1 -1
- package/lib/operations/delete.js +5 -5
- package/lib/operations/delete.js.map +1 -1
- package/lib/operations/distinct.js +2 -2
- package/lib/operations/distinct.js.map +1 -1
- package/lib/operations/estimated_document_count.js +5 -1
- package/lib/operations/estimated_document_count.js.map +1 -1
- package/lib/operations/eval.js.map +1 -1
- package/lib/operations/execute_operation.js +31 -17
- package/lib/operations/execute_operation.js.map +1 -1
- package/lib/operations/find.js +13 -9
- package/lib/operations/find.js.map +1 -1
- package/lib/operations/find_and_modify.js +9 -9
- package/lib/operations/find_and_modify.js.map +1 -1
- package/lib/operations/indexes.js +8 -3
- package/lib/operations/indexes.js.map +1 -1
- package/lib/operations/insert.js +5 -3
- package/lib/operations/insert.js.map +1 -1
- package/lib/operations/is_capped.js +2 -1
- package/lib/operations/is_capped.js.map +1 -1
- package/lib/operations/list_collections.js +6 -3
- package/lib/operations/list_collections.js.map +1 -1
- package/lib/operations/map_reduce.js +1 -1
- package/lib/operations/map_reduce.js.map +1 -1
- package/lib/operations/operation.js +3 -1
- package/lib/operations/operation.js.map +1 -1
- package/lib/operations/options_operation.js +2 -1
- package/lib/operations/options_operation.js.map +1 -1
- package/lib/operations/profiling_level.js +4 -2
- package/lib/operations/profiling_level.js.map +1 -1
- package/lib/operations/set_profiling_level.js +4 -2
- package/lib/operations/set_profiling_level.js.map +1 -1
- package/lib/operations/update.js +12 -12
- package/lib/operations/update.js.map +1 -1
- package/lib/operations/validate_collection.js +6 -5
- package/lib/operations/validate_collection.js.map +1 -1
- package/lib/promise_provider.js +1 -1
- package/lib/promise_provider.js.map +1 -1
- package/lib/read_preference.js +8 -8
- package/lib/read_preference.js.map +1 -1
- package/lib/sdam/common.js +12 -10
- package/lib/sdam/common.js.map +1 -1
- package/lib/sdam/server.js +90 -25
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/server_description.js +9 -4
- package/lib/sdam/server_description.js.map +1 -1
- package/lib/sdam/server_selection.js +10 -4
- package/lib/sdam/server_selection.js.map +1 -1
- package/lib/sdam/srv_polling.js +1 -1
- package/lib/sdam/srv_polling.js.map +1 -1
- package/lib/sdam/topology.js +42 -21
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sdam/topology_description.js +7 -3
- package/lib/sdam/topology_description.js.map +1 -1
- package/lib/sessions.js +132 -31
- package/lib/sessions.js.map +1 -1
- package/lib/sort.js +3 -3
- package/lib/sort.js.map +1 -1
- package/lib/transactions.js +15 -7
- package/lib/transactions.js.map +1 -1
- package/lib/utils.js +60 -20
- package/lib/utils.js.map +1 -1
- package/mongodb.d.ts +523 -138
- package/mongodb.ts34.d.ts +480 -141
- package/package.json +44 -48
- package/src/bson.ts +1 -0
- package/src/bulk/common.ts +83 -43
- package/src/bulk/ordered.ts +4 -3
- package/src/bulk/unordered.ts +4 -3
- package/src/change_stream.ts +46 -29
- package/src/cmap/auth/auth_provider.ts +3 -2
- package/src/cmap/auth/gssapi.ts +15 -5
- package/src/cmap/auth/mongo_credentials.ts +22 -8
- package/src/cmap/auth/mongocr.ts +3 -3
- package/src/cmap/auth/mongodb_aws.ts +52 -39
- package/src/cmap/auth/plain.ts +2 -2
- package/src/cmap/auth/scram.ts +23 -13
- package/src/cmap/auth/x509.ts +3 -3
- package/src/cmap/command_monitoring_events.ts +36 -14
- package/src/cmap/commands.ts +12 -6
- package/src/cmap/connect.ts +42 -12
- package/src/cmap/connection.ts +54 -62
- package/src/cmap/connection_pool.ts +141 -20
- package/src/cmap/connection_pool_events.ts +8 -1
- package/src/cmap/errors.ts +3 -4
- package/src/cmap/message_stream.ts +2 -4
- package/src/cmap/metrics.ts +58 -0
- package/src/cmap/stream_description.ts +6 -1
- package/src/cmap/wire_protocol/compression.ts +26 -13
- package/src/cmap/wire_protocol/shared.ts +4 -2
- package/src/collection.ts +75 -70
- package/src/connection_string.ts +97 -34
- package/src/cursor/abstract_cursor.ts +141 -104
- package/src/cursor/aggregation_cursor.ts +34 -20
- package/src/cursor/find_cursor.ts +41 -21
- package/src/db.ts +19 -18
- package/src/deps.ts +110 -22
- package/src/encrypter.ts +6 -12
- package/src/error.ts +264 -48
- package/src/explain.ts +3 -3
- package/src/gridfs/download.ts +48 -53
- package/src/gridfs/index.ts +5 -4
- package/src/gridfs/upload.ts +32 -33
- package/src/index.ts +42 -4
- package/src/logger.ts +6 -3
- package/src/mongo_client.ts +20 -23
- package/src/mongo_types.ts +19 -20
- package/src/operations/add_user.ts +4 -5
- package/src/operations/aggregate.ts +18 -17
- package/src/operations/command.ts +7 -10
- package/src/operations/common_functions.ts +2 -3
- package/src/operations/connect.ts +4 -3
- package/src/operations/count.ts +2 -2
- package/src/operations/count_documents.ts +2 -2
- package/src/operations/delete.ts +8 -6
- package/src/operations/distinct.ts +5 -3
- package/src/operations/estimated_document_count.ts +5 -1
- package/src/operations/eval.ts +1 -1
- package/src/operations/execute_operation.ts +41 -20
- package/src/operations/find.ts +25 -16
- package/src/operations/find_and_modify.ts +12 -10
- package/src/operations/indexes.ts +39 -8
- package/src/operations/insert.ts +7 -4
- package/src/operations/is_capped.ts +3 -2
- package/src/operations/list_collections.ts +9 -6
- package/src/operations/map_reduce.ts +4 -2
- package/src/operations/operation.ts +7 -2
- package/src/operations/options_operation.ts +3 -2
- package/src/operations/profiling_level.ts +5 -3
- package/src/operations/set_profiling_level.ts +9 -3
- package/src/operations/update.ts +17 -13
- package/src/operations/validate_collection.ts +7 -6
- package/src/promise_provider.ts +2 -2
- package/src/read_preference.ts +11 -9
- package/src/sdam/common.ts +11 -9
- package/src/sdam/server.ts +168 -69
- package/src/sdam/server_description.ts +16 -4
- package/src/sdam/server_selection.ts +15 -7
- package/src/sdam/srv_polling.ts +2 -2
- package/src/sdam/topology.ts +67 -36
- package/src/sdam/topology_description.ts +11 -4
- package/src/sessions.ts +194 -37
- package/src/sort.ts +6 -4
- package/src/transactions.ts +18 -9
- package/src/utils.ts +73 -20
- package/HISTORY.md +0 -2993
- package/lib/operations/find_one.js +0 -34
- package/lib/operations/find_one.js.map +0 -1
- package/src/operations/find_one.ts +0 -43
package/src/sdam/common.ts
CHANGED
|
@@ -17,7 +17,8 @@ export const TopologyType = Object.freeze({
|
|
|
17
17
|
ReplicaSetNoPrimary: 'ReplicaSetNoPrimary',
|
|
18
18
|
ReplicaSetWithPrimary: 'ReplicaSetWithPrimary',
|
|
19
19
|
Sharded: 'Sharded',
|
|
20
|
-
Unknown: 'Unknown'
|
|
20
|
+
Unknown: 'Unknown',
|
|
21
|
+
LoadBalanced: 'LoadBalanced'
|
|
21
22
|
} as const);
|
|
22
23
|
|
|
23
24
|
/** @public */
|
|
@@ -36,7 +37,8 @@ export const ServerType = Object.freeze({
|
|
|
36
37
|
RSArbiter: 'RSArbiter',
|
|
37
38
|
RSOther: 'RSOther',
|
|
38
39
|
RSGhost: 'RSGhost',
|
|
39
|
-
Unknown: 'Unknown'
|
|
40
|
+
Unknown: 'Unknown',
|
|
41
|
+
LoadBalancer: 'LoadBalancer'
|
|
40
42
|
} as const);
|
|
41
43
|
|
|
42
44
|
/** @public */
|
|
@@ -66,16 +68,16 @@ export interface ClusterTime {
|
|
|
66
68
|
};
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
/** Shared function to determine clusterTime for a given topology */
|
|
70
|
-
export function
|
|
71
|
-
|
|
71
|
+
/** Shared function to determine clusterTime for a given topology or session */
|
|
72
|
+
export function _advanceClusterTime(
|
|
73
|
+
entity: Topology | ClientSession,
|
|
72
74
|
$clusterTime: ClusterTime
|
|
73
75
|
): void {
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
+
if (entity.clusterTime == null) {
|
|
77
|
+
entity.clusterTime = $clusterTime;
|
|
76
78
|
} else {
|
|
77
|
-
if ($clusterTime.clusterTime.greaterThan(
|
|
78
|
-
|
|
79
|
+
if ($clusterTime.clusterTime.greaterThan(entity.clusterTime.clusterTime)) {
|
|
80
|
+
entity.clusterTime = $clusterTime;
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
}
|
package/src/sdam/server.ts
CHANGED
|
@@ -18,12 +18,12 @@ import {
|
|
|
18
18
|
EventEmitterWithState
|
|
19
19
|
} from '../utils';
|
|
20
20
|
import {
|
|
21
|
-
ServerType,
|
|
22
21
|
STATE_CLOSED,
|
|
23
22
|
STATE_CLOSING,
|
|
24
23
|
STATE_CONNECTING,
|
|
25
24
|
STATE_CONNECTED,
|
|
26
|
-
ClusterTime
|
|
25
|
+
ClusterTime,
|
|
26
|
+
TopologyType
|
|
27
27
|
} from './common';
|
|
28
28
|
import {
|
|
29
29
|
MongoError,
|
|
@@ -33,7 +33,9 @@ import {
|
|
|
33
33
|
isRetryableWriteError,
|
|
34
34
|
isNodeShuttingDownError,
|
|
35
35
|
isNetworkErrorBeforeHandshake,
|
|
36
|
-
|
|
36
|
+
MongoCompatibilityError,
|
|
37
|
+
MongoInvalidArgumentError,
|
|
38
|
+
MongoServerClosedError
|
|
37
39
|
} from '../error';
|
|
38
40
|
import {
|
|
39
41
|
Connection,
|
|
@@ -54,6 +56,7 @@ import type { Document, Long } from '../bson';
|
|
|
54
56
|
import type { AutoEncrypter } from '../deps';
|
|
55
57
|
import type { ServerApi } from '../mongo_client';
|
|
56
58
|
import { TypedEventEmitter } from '../mongo_types';
|
|
59
|
+
import { supportsRetryableWrites } from '../utils';
|
|
57
60
|
|
|
58
61
|
const stateTransition = makeStateMachine({
|
|
59
62
|
[STATE_CLOSED]: [STATE_CLOSED, STATE_CONNECTING],
|
|
@@ -151,6 +154,9 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
151
154
|
this.clusterTime = clusterTime;
|
|
152
155
|
});
|
|
153
156
|
|
|
157
|
+
// monitoring is disabled in load balancing mode
|
|
158
|
+
if (this.loadBalanced) return;
|
|
159
|
+
|
|
154
160
|
// create the monitor
|
|
155
161
|
this[kMonitor] = new Monitor(this, this.s.options);
|
|
156
162
|
|
|
@@ -192,6 +198,10 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
192
198
|
}
|
|
193
199
|
}
|
|
194
200
|
|
|
201
|
+
get loadBalanced(): boolean {
|
|
202
|
+
return this.s.topology.description.type === TopologyType.LoadBalanced;
|
|
203
|
+
}
|
|
204
|
+
|
|
195
205
|
/**
|
|
196
206
|
* Initiate server connect
|
|
197
207
|
*/
|
|
@@ -201,7 +211,16 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
201
211
|
}
|
|
202
212
|
|
|
203
213
|
stateTransition(this, STATE_CONNECTING);
|
|
204
|
-
|
|
214
|
+
|
|
215
|
+
// If in load balancer mode we automatically set the server to
|
|
216
|
+
// a load balancer. It never transitions out of this state and
|
|
217
|
+
// has no monitor.
|
|
218
|
+
if (!this.loadBalanced) {
|
|
219
|
+
this[kMonitor].connect();
|
|
220
|
+
} else {
|
|
221
|
+
stateTransition(this, STATE_CONNECTED);
|
|
222
|
+
this.emit(Server.CONNECT, this);
|
|
223
|
+
}
|
|
205
224
|
}
|
|
206
225
|
|
|
207
226
|
/** Destroy the server connection */
|
|
@@ -219,7 +238,10 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
219
238
|
|
|
220
239
|
stateTransition(this, STATE_CLOSING);
|
|
221
240
|
|
|
222
|
-
this
|
|
241
|
+
if (!this.loadBalanced) {
|
|
242
|
+
this[kMonitor].close();
|
|
243
|
+
}
|
|
244
|
+
|
|
223
245
|
this.s.pool.close(options, err => {
|
|
224
246
|
stateTransition(this, STATE_CLOSED);
|
|
225
247
|
this.emit('closed');
|
|
@@ -234,7 +256,9 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
234
256
|
* this will be a no-op.
|
|
235
257
|
*/
|
|
236
258
|
requestCheck(): void {
|
|
237
|
-
this
|
|
259
|
+
if (!this.loadBalanced) {
|
|
260
|
+
this[kMonitor].requestCheck();
|
|
261
|
+
}
|
|
238
262
|
}
|
|
239
263
|
|
|
240
264
|
/**
|
|
@@ -260,15 +284,15 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
260
284
|
}
|
|
261
285
|
|
|
262
286
|
if (callback == null) {
|
|
263
|
-
throw new
|
|
287
|
+
throw new MongoInvalidArgumentError('Callback must be provided');
|
|
264
288
|
}
|
|
265
289
|
|
|
266
290
|
if (ns.db == null || typeof ns === 'string') {
|
|
267
|
-
throw new
|
|
291
|
+
throw new MongoInvalidArgumentError('Namespace must not be a string');
|
|
268
292
|
}
|
|
269
293
|
|
|
270
294
|
if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) {
|
|
271
|
-
callback(new
|
|
295
|
+
callback(new MongoServerClosedError());
|
|
272
296
|
return;
|
|
273
297
|
}
|
|
274
298
|
|
|
@@ -277,23 +301,47 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
277
301
|
|
|
278
302
|
// error if collation not supported
|
|
279
303
|
if (collationNotSupported(this, cmd)) {
|
|
280
|
-
callback(new
|
|
304
|
+
callback(new MongoCompatibilityError(`Server ${this.name} does not support collation`));
|
|
281
305
|
return;
|
|
282
306
|
}
|
|
283
307
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
308
|
+
const session = finalOptions.session;
|
|
309
|
+
const conn = session?.pinnedConnection;
|
|
310
|
+
|
|
311
|
+
// NOTE: This is a hack! We can't retrieve the connections used for executing an operation
|
|
312
|
+
// (and prevent them from being checked back in) at the point of operation execution.
|
|
313
|
+
// This should be considered as part of the work for NODE-2882
|
|
314
|
+
if (this.loadBalanced && session && conn == null && isPinnableCommand(cmd, session)) {
|
|
315
|
+
this.s.pool.checkOut((err, checkedOut) => {
|
|
316
|
+
if (err || checkedOut == null) {
|
|
317
|
+
if (callback) return callback(err);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
289
320
|
|
|
290
|
-
|
|
291
|
-
ns,
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
321
|
+
session.pin(checkedOut);
|
|
322
|
+
this.command(ns, cmd, finalOptions, callback as Callback<Document>);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
this.s.pool.withConnection(
|
|
329
|
+
conn,
|
|
330
|
+
(err, conn, cb) => {
|
|
331
|
+
if (err || !conn) {
|
|
332
|
+
markServerUnknown(this, err);
|
|
333
|
+
return cb(err);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
conn.command(
|
|
337
|
+
ns,
|
|
338
|
+
cmd,
|
|
339
|
+
finalOptions,
|
|
340
|
+
makeOperationHandler(this, conn, cmd, finalOptions, cb) as Callback<Document>
|
|
341
|
+
);
|
|
342
|
+
},
|
|
343
|
+
callback
|
|
344
|
+
);
|
|
297
345
|
}
|
|
298
346
|
|
|
299
347
|
/**
|
|
@@ -302,18 +350,27 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
302
350
|
*/
|
|
303
351
|
query(ns: MongoDBNamespace, cmd: Document, options: QueryOptions, callback: Callback): void {
|
|
304
352
|
if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) {
|
|
305
|
-
callback(new
|
|
353
|
+
callback(new MongoServerClosedError());
|
|
306
354
|
return;
|
|
307
355
|
}
|
|
308
356
|
|
|
309
|
-
this.s.pool.withConnection(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
357
|
+
this.s.pool.withConnection(
|
|
358
|
+
undefined,
|
|
359
|
+
(err, conn, cb) => {
|
|
360
|
+
if (err || !conn) {
|
|
361
|
+
markServerUnknown(this, err);
|
|
362
|
+
return cb(err);
|
|
363
|
+
}
|
|
314
364
|
|
|
315
|
-
|
|
316
|
-
|
|
365
|
+
conn.query(
|
|
366
|
+
ns,
|
|
367
|
+
cmd,
|
|
368
|
+
options,
|
|
369
|
+
makeOperationHandler(this, conn, cmd, options, cb) as Callback
|
|
370
|
+
);
|
|
371
|
+
},
|
|
372
|
+
callback
|
|
373
|
+
);
|
|
317
374
|
}
|
|
318
375
|
|
|
319
376
|
/**
|
|
@@ -327,23 +384,27 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
327
384
|
callback: Callback<Document>
|
|
328
385
|
): void {
|
|
329
386
|
if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) {
|
|
330
|
-
callback(new
|
|
387
|
+
callback(new MongoServerClosedError());
|
|
331
388
|
return;
|
|
332
389
|
}
|
|
333
390
|
|
|
334
|
-
this.s.pool.withConnection(
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
391
|
+
this.s.pool.withConnection(
|
|
392
|
+
options.session?.pinnedConnection,
|
|
393
|
+
(err, conn, cb) => {
|
|
394
|
+
if (err || !conn) {
|
|
395
|
+
markServerUnknown(this, err);
|
|
396
|
+
return cb(err);
|
|
397
|
+
}
|
|
339
398
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
399
|
+
conn.getMore(
|
|
400
|
+
ns,
|
|
401
|
+
cursorId,
|
|
402
|
+
options,
|
|
403
|
+
makeOperationHandler(this, conn, {}, options, cb) as Callback
|
|
404
|
+
);
|
|
405
|
+
},
|
|
406
|
+
callback
|
|
407
|
+
);
|
|
347
408
|
}
|
|
348
409
|
|
|
349
410
|
/**
|
|
@@ -358,25 +419,29 @@ export class Server extends TypedEventEmitter<ServerEvents> {
|
|
|
358
419
|
): void {
|
|
359
420
|
if (this.s.state === STATE_CLOSING || this.s.state === STATE_CLOSED) {
|
|
360
421
|
if (typeof callback === 'function') {
|
|
361
|
-
callback(new
|
|
422
|
+
callback(new MongoServerClosedError());
|
|
362
423
|
}
|
|
363
424
|
|
|
364
425
|
return;
|
|
365
426
|
}
|
|
366
427
|
|
|
367
|
-
this.s.pool.withConnection(
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
428
|
+
this.s.pool.withConnection(
|
|
429
|
+
options.session?.pinnedConnection,
|
|
430
|
+
(err, conn, cb) => {
|
|
431
|
+
if (err || !conn) {
|
|
432
|
+
markServerUnknown(this, err);
|
|
433
|
+
return cb(err);
|
|
434
|
+
}
|
|
372
435
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
436
|
+
conn.killCursors(
|
|
437
|
+
ns,
|
|
438
|
+
cursorIds,
|
|
439
|
+
options,
|
|
440
|
+
makeOperationHandler(this, conn, {}, undefined, cb) as Callback
|
|
441
|
+
);
|
|
442
|
+
},
|
|
443
|
+
callback
|
|
444
|
+
);
|
|
380
445
|
}
|
|
381
446
|
}
|
|
382
447
|
|
|
@@ -395,14 +460,6 @@ Object.defineProperty(Server.prototype, 'clusterTime', {
|
|
|
395
460
|
}
|
|
396
461
|
});
|
|
397
462
|
|
|
398
|
-
function supportsRetryableWrites(server: Server) {
|
|
399
|
-
return (
|
|
400
|
-
server.description.maxWireVersion >= 6 &&
|
|
401
|
-
server.description.logicalSessionTimeoutMinutes &&
|
|
402
|
-
server.description.type !== ServerType.Standalone
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
463
|
function calculateRoundTripTime(oldRtt: number, duration: number): number {
|
|
407
464
|
if (oldRtt === -1) {
|
|
408
465
|
return duration;
|
|
@@ -413,6 +470,11 @@ function calculateRoundTripTime(oldRtt: number, duration: number): number {
|
|
|
413
470
|
}
|
|
414
471
|
|
|
415
472
|
function markServerUnknown(server: Server, error?: MongoError) {
|
|
473
|
+
// Load balancer servers can never be marked unknown.
|
|
474
|
+
if (server.loadBalanced) {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
|
|
416
478
|
if (error instanceof MongoNetworkError && !(error instanceof MongoNetworkTimeoutError)) {
|
|
417
479
|
server[kMonitor].reset();
|
|
418
480
|
}
|
|
@@ -427,7 +489,28 @@ function markServerUnknown(server: Server, error?: MongoError) {
|
|
|
427
489
|
);
|
|
428
490
|
}
|
|
429
491
|
|
|
492
|
+
function isPinnableCommand(cmd: Document, session?: ClientSession): boolean {
|
|
493
|
+
if (session) {
|
|
494
|
+
return (
|
|
495
|
+
session.inTransaction() ||
|
|
496
|
+
'aggregate' in cmd ||
|
|
497
|
+
'find' in cmd ||
|
|
498
|
+
'getMore' in cmd ||
|
|
499
|
+
'listCollections' in cmd ||
|
|
500
|
+
'listIndexes' in cmd
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
|
|
430
507
|
function connectionIsStale(pool: ConnectionPool, connection: Connection) {
|
|
508
|
+
if (connection.serviceId) {
|
|
509
|
+
return (
|
|
510
|
+
connection.generation !== pool.serviceGenerations.get(connection.serviceId.toHexString())
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
|
|
431
514
|
return connection.generation !== pool.generation;
|
|
432
515
|
}
|
|
433
516
|
|
|
@@ -462,6 +545,11 @@ function makeOperationHandler(
|
|
|
462
545
|
session.serverSession.isDirty = true;
|
|
463
546
|
}
|
|
464
547
|
|
|
548
|
+
// inActiveTransaction check handles commit and abort.
|
|
549
|
+
if (inActiveTransaction(session, cmd) && !err.hasErrorLabel('TransientTransactionError')) {
|
|
550
|
+
err.addErrorLabel('TransientTransactionError');
|
|
551
|
+
}
|
|
552
|
+
|
|
465
553
|
if (
|
|
466
554
|
(isRetryableWritesEnabled(server.s.topology) || isTransactionCommand(cmd)) &&
|
|
467
555
|
supportsRetryableWrites(server) &&
|
|
@@ -471,8 +559,13 @@ function makeOperationHandler(
|
|
|
471
559
|
}
|
|
472
560
|
|
|
473
561
|
if (!(err instanceof MongoNetworkTimeoutError) || isNetworkErrorBeforeHandshake(err)) {
|
|
474
|
-
|
|
475
|
-
|
|
562
|
+
// In load balanced mode we never mark the server as unknown and always
|
|
563
|
+
// clear for the specific service id.
|
|
564
|
+
|
|
565
|
+
server.s.pool.clear(connection.serviceId);
|
|
566
|
+
if (!server.loadBalanced) {
|
|
567
|
+
markServerUnknown(server, err);
|
|
568
|
+
}
|
|
476
569
|
}
|
|
477
570
|
} else {
|
|
478
571
|
// if pre-4.4 server, then add error label if its a retryable write error
|
|
@@ -488,14 +581,20 @@ function makeOperationHandler(
|
|
|
488
581
|
if (isSDAMUnrecoverableError(err)) {
|
|
489
582
|
if (shouldHandleStateChangeError(server, err)) {
|
|
490
583
|
if (maxWireVersion(server) <= 7 || isNodeShuttingDownError(err)) {
|
|
491
|
-
server.s.pool.clear();
|
|
584
|
+
server.s.pool.clear(connection.serviceId);
|
|
492
585
|
}
|
|
493
586
|
|
|
494
|
-
|
|
495
|
-
|
|
587
|
+
if (!server.loadBalanced) {
|
|
588
|
+
markServerUnknown(server, err);
|
|
589
|
+
process.nextTick(() => server.requestCheck());
|
|
590
|
+
}
|
|
496
591
|
}
|
|
497
592
|
}
|
|
498
593
|
}
|
|
594
|
+
|
|
595
|
+
if (session && session.isPinned && err.hasErrorLabel('TransientTransactionError')) {
|
|
596
|
+
session.unpin({ force: true });
|
|
597
|
+
}
|
|
499
598
|
}
|
|
500
599
|
|
|
501
600
|
callback(err, result);
|
|
@@ -7,14 +7,16 @@ import type { MongoError } from '../error';
|
|
|
7
7
|
const WRITABLE_SERVER_TYPES = new Set<ServerType>([
|
|
8
8
|
ServerType.RSPrimary,
|
|
9
9
|
ServerType.Standalone,
|
|
10
|
-
ServerType.Mongos
|
|
10
|
+
ServerType.Mongos,
|
|
11
|
+
ServerType.LoadBalancer
|
|
11
12
|
]);
|
|
12
13
|
|
|
13
14
|
const DATA_BEARING_SERVER_TYPES = new Set<ServerType>([
|
|
14
15
|
ServerType.RSPrimary,
|
|
15
16
|
ServerType.RSSecondary,
|
|
16
17
|
ServerType.Mongos,
|
|
17
|
-
ServerType.Standalone
|
|
18
|
+
ServerType.Standalone,
|
|
19
|
+
ServerType.LoadBalancer
|
|
18
20
|
]);
|
|
19
21
|
|
|
20
22
|
/** @public */
|
|
@@ -36,6 +38,9 @@ export interface ServerDescriptionOptions {
|
|
|
36
38
|
|
|
37
39
|
/** The topologyVersion */
|
|
38
40
|
topologyVersion?: TopologyVersion;
|
|
41
|
+
|
|
42
|
+
/** If the client is in load balancing mode. */
|
|
43
|
+
loadBalanced?: boolean;
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
/**
|
|
@@ -90,7 +95,7 @@ export class ServerDescription {
|
|
|
90
95
|
this._hostAddress = address;
|
|
91
96
|
this.address = this._hostAddress.toString();
|
|
92
97
|
}
|
|
93
|
-
this.type = parseServerType(ismaster);
|
|
98
|
+
this.type = parseServerType(ismaster, options);
|
|
94
99
|
this.hosts = ismaster?.hosts?.map((host: string) => host.toLowerCase()) ?? [];
|
|
95
100
|
this.passives = ismaster?.passives?.map((host: string) => host.toLowerCase()) ?? [];
|
|
96
101
|
this.arbiters = ismaster?.arbiters?.map((host: string) => host.toLowerCase()) ?? [];
|
|
@@ -206,7 +211,14 @@ export class ServerDescription {
|
|
|
206
211
|
}
|
|
207
212
|
|
|
208
213
|
// Parses an `ismaster` message and determines the server type
|
|
209
|
-
export function parseServerType(
|
|
214
|
+
export function parseServerType(
|
|
215
|
+
ismaster?: Document,
|
|
216
|
+
options?: ServerDescriptionOptions
|
|
217
|
+
): ServerType {
|
|
218
|
+
if (options?.loadBalanced) {
|
|
219
|
+
return ServerType.LoadBalancer;
|
|
220
|
+
}
|
|
221
|
+
|
|
210
222
|
if (!ismaster || !ismaster.ok) {
|
|
211
223
|
return ServerType.Unknown;
|
|
212
224
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ServerType, TopologyType } from './common';
|
|
2
2
|
import { ReadPreference } from '../read_preference';
|
|
3
|
-
import {
|
|
3
|
+
import { MongoCompatibilityError, MongoInvalidArgumentError } from '../error';
|
|
4
4
|
import type { TopologyDescription } from './topology_description';
|
|
5
5
|
import type { ServerDescription, TagSet } from './server_description';
|
|
6
6
|
|
|
@@ -50,14 +50,14 @@ function maxStalenessReducer(
|
|
|
50
50
|
const maxStalenessVariance =
|
|
51
51
|
(topologyDescription.heartbeatFrequencyMS + IDLE_WRITE_PERIOD) / 1000;
|
|
52
52
|
if (maxStaleness < maxStalenessVariance) {
|
|
53
|
-
throw new
|
|
54
|
-
`maxStalenessSeconds must be at least ${maxStalenessVariance} seconds`
|
|
53
|
+
throw new MongoInvalidArgumentError(
|
|
54
|
+
`Option "maxStalenessSeconds" must be at least ${maxStalenessVariance} seconds`
|
|
55
55
|
);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
if (maxStaleness < SMALLEST_MAX_STALENESS_SECONDS) {
|
|
59
|
-
throw new
|
|
60
|
-
`maxStalenessSeconds must be at least ${SMALLEST_MAX_STALENESS_SECONDS} seconds`
|
|
59
|
+
throw new MongoInvalidArgumentError(
|
|
60
|
+
`Option "maxStalenessSeconds" must be at least ${SMALLEST_MAX_STALENESS_SECONDS} seconds`
|
|
61
61
|
);
|
|
62
62
|
}
|
|
63
63
|
|
|
@@ -207,6 +207,10 @@ function knownFilter(server: ServerDescription): boolean {
|
|
|
207
207
|
return server.type !== ServerType.Unknown;
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
function loadBalancerFilter(server: ServerDescription): boolean {
|
|
211
|
+
return server.type === ServerType.LoadBalancer;
|
|
212
|
+
}
|
|
213
|
+
|
|
210
214
|
/**
|
|
211
215
|
* Returns a function which selects servers based on a provided read preference
|
|
212
216
|
*
|
|
@@ -214,7 +218,7 @@ function knownFilter(server: ServerDescription): boolean {
|
|
|
214
218
|
*/
|
|
215
219
|
export function readPreferenceServerSelector(readPreference: ReadPreference): ServerSelector {
|
|
216
220
|
if (!readPreference.isValid()) {
|
|
217
|
-
throw new
|
|
221
|
+
throw new MongoInvalidArgumentError('Invalid read preference specified');
|
|
218
222
|
}
|
|
219
223
|
|
|
220
224
|
return (
|
|
@@ -227,11 +231,15 @@ export function readPreferenceServerSelector(readPreference: ReadPreference): Se
|
|
|
227
231
|
readPreference.minWireVersion &&
|
|
228
232
|
readPreference.minWireVersion > commonWireVersion
|
|
229
233
|
) {
|
|
230
|
-
throw new
|
|
234
|
+
throw new MongoCompatibilityError(
|
|
231
235
|
`Minimum wire version '${readPreference.minWireVersion}' required, but found '${commonWireVersion}'`
|
|
232
236
|
);
|
|
233
237
|
}
|
|
234
238
|
|
|
239
|
+
if (topologyDescription.type === TopologyType.LoadBalanced) {
|
|
240
|
+
return servers.filter(loadBalancerFilter);
|
|
241
|
+
}
|
|
242
|
+
|
|
235
243
|
if (topologyDescription.type === TopologyType.Unknown) {
|
|
236
244
|
return [];
|
|
237
245
|
}
|
package/src/sdam/srv_polling.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as dns from 'dns';
|
|
|
2
2
|
import { Logger, LoggerOptions } from '../logger';
|
|
3
3
|
import { HostAddress } from '../utils';
|
|
4
4
|
import { TypedEventEmitter } from '../mongo_types';
|
|
5
|
-
import {
|
|
5
|
+
import { MongoRuntimeError } from '../error';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Determines whether a provided address matches the provided parent domain in order
|
|
@@ -67,7 +67,7 @@ export class SrvPoller extends TypedEventEmitter<SrvPollerEvents> {
|
|
|
67
67
|
super();
|
|
68
68
|
|
|
69
69
|
if (!options || !options.srvHost) {
|
|
70
|
-
throw new
|
|
70
|
+
throw new MongoRuntimeError('Options for SrvPoller must exist and include srvHost');
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
this.srvHost = options.srvHost;
|