mongodb 6.12.0-dev.20241211.sha.2f9ad4d4 → 6.12.0-dev.20241212.sha.f6d7868f
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/lib/beta.d.ts +16 -85
- package/lib/bulk/common.js +5 -7
- package/lib/bulk/common.js.map +1 -1
- package/lib/change_stream.js +16 -26
- package/lib/change_stream.js.map +1 -1
- package/lib/cmap/connection_pool.js +83 -117
- package/lib/cmap/connection_pool.js.map +1 -1
- package/lib/encrypter.js +5 -9
- package/lib/encrypter.js.map +1 -1
- package/lib/error.js +10 -18
- package/lib/error.js.map +1 -1
- package/lib/mongo_client.js +20 -26
- package/lib/mongo_client.js.map +1 -1
- package/lib/operations/operation.js +4 -5
- package/lib/operations/operation.js.map +1 -1
- package/lib/sdam/monitor.js +25 -31
- package/lib/sdam/monitor.js.map +1 -1
- package/lib/sdam/server.js +1 -1
- package/lib/sdam/server.js.map +1 -1
- package/lib/sdam/topology.js +13 -16
- package/lib/sdam/topology.js.map +1 -1
- package/lib/sessions.js +24 -48
- package/lib/sessions.js.map +1 -1
- package/mongodb.d.ts +16 -85
- package/package.json +1 -1
- package/src/bulk/common.ts +6 -9
- package/src/change_stream.ts +21 -33
- package/src/cmap/connection_pool.ts +104 -142
- package/src/encrypter.ts +6 -11
- package/src/error.ts +11 -23
- package/src/mongo_client.ts +26 -32
- package/src/operations/operation.ts +5 -7
- package/src/sdam/monitor.ts +30 -38
- package/src/sdam/server.ts +2 -2
- package/src/sdam/topology.ts +15 -19
- package/src/sessions.ts +37 -58
|
@@ -52,35 +52,6 @@ import {
|
|
|
52
52
|
} from './errors';
|
|
53
53
|
import { ConnectionPoolMetrics } from './metrics';
|
|
54
54
|
|
|
55
|
-
/** @internal */
|
|
56
|
-
const kServer = Symbol('server');
|
|
57
|
-
/** @internal */
|
|
58
|
-
const kConnections = Symbol('connections');
|
|
59
|
-
/** @internal */
|
|
60
|
-
const kPending = Symbol('pending');
|
|
61
|
-
/** @internal */
|
|
62
|
-
const kCheckedOut = Symbol('checkedOut');
|
|
63
|
-
/** @internal */
|
|
64
|
-
const kMinPoolSizeTimer = Symbol('minPoolSizeTimer');
|
|
65
|
-
/** @internal */
|
|
66
|
-
const kGeneration = Symbol('generation');
|
|
67
|
-
/** @internal */
|
|
68
|
-
const kServiceGenerations = Symbol('serviceGenerations');
|
|
69
|
-
/** @internal */
|
|
70
|
-
const kConnectionCounter = Symbol('connectionCounter');
|
|
71
|
-
/** @internal */
|
|
72
|
-
const kCancellationToken = Symbol('cancellationToken');
|
|
73
|
-
/** @internal */
|
|
74
|
-
const kWaitQueue = Symbol('waitQueue');
|
|
75
|
-
/** @internal */
|
|
76
|
-
const kCancelled = Symbol('cancelled');
|
|
77
|
-
/** @internal */
|
|
78
|
-
const kMetrics = Symbol('metrics');
|
|
79
|
-
/** @internal */
|
|
80
|
-
const kProcessingWaitQueue = Symbol('processingWaitQueue');
|
|
81
|
-
/** @internal */
|
|
82
|
-
const kPoolState = Symbol('poolState');
|
|
83
|
-
|
|
84
55
|
/** @public */
|
|
85
56
|
export interface ConnectionPoolOptions extends Omit<ConnectionOptions, 'id' | 'generation'> {
|
|
86
57
|
/** The maximum number of connections that may be associated with a pool at a given time. This includes in use and available connections. */
|
|
@@ -103,7 +74,7 @@ export interface ConnectionPoolOptions extends Omit<ConnectionOptions, 'id' | 'g
|
|
|
103
74
|
export interface WaitQueueMember {
|
|
104
75
|
resolve: (conn: Connection) => void;
|
|
105
76
|
reject: (err: AnyError) => void;
|
|
106
|
-
|
|
77
|
+
cancelled: boolean;
|
|
107
78
|
checkoutTime: number;
|
|
108
79
|
}
|
|
109
80
|
|
|
@@ -114,6 +85,8 @@ export const PoolState = Object.freeze({
|
|
|
114
85
|
closed: 'closed'
|
|
115
86
|
} as const);
|
|
116
87
|
|
|
88
|
+
type PoolState = (typeof PoolState)[keyof typeof PoolState];
|
|
89
|
+
|
|
117
90
|
/**
|
|
118
91
|
* @public
|
|
119
92
|
* @deprecated This interface is deprecated and will be removed in a future release as it is not used
|
|
@@ -143,26 +116,23 @@ export type ConnectionPoolEvents = {
|
|
|
143
116
|
* @internal
|
|
144
117
|
*/
|
|
145
118
|
export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
146
|
-
options: Readonly<ConnectionPoolOptions>;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
[kWaitQueue]: List<WaitQueueMember>;
|
|
164
|
-
[kMetrics]: ConnectionPoolMetrics;
|
|
165
|
-
[kProcessingWaitQueue]: boolean;
|
|
119
|
+
public options: Readonly<ConnectionPoolOptions>;
|
|
120
|
+
/** An integer representing the SDAM generation of the pool */
|
|
121
|
+
public generation: number;
|
|
122
|
+
/** A map of generations to service ids */
|
|
123
|
+
public serviceGenerations: Map<string, number>;
|
|
124
|
+
|
|
125
|
+
private poolState: PoolState;
|
|
126
|
+
private server: Server;
|
|
127
|
+
private connections: List<Connection>;
|
|
128
|
+
private pending: number;
|
|
129
|
+
private checkedOut: Set<Connection>;
|
|
130
|
+
private minPoolSizeTimer?: NodeJS.Timeout;
|
|
131
|
+
private connectionCounter: Generator<number>;
|
|
132
|
+
private cancellationToken: CancellationToken;
|
|
133
|
+
private waitQueue: List<WaitQueueMember>;
|
|
134
|
+
private metrics: ConnectionPoolMetrics;
|
|
135
|
+
private processingWaitQueue: boolean;
|
|
166
136
|
|
|
167
137
|
/**
|
|
168
138
|
* Emitted when the connection pool is created.
|
|
@@ -241,22 +211,22 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
241
211
|
);
|
|
242
212
|
}
|
|
243
213
|
|
|
244
|
-
this
|
|
245
|
-
this
|
|
246
|
-
this
|
|
247
|
-
this
|
|
248
|
-
this
|
|
249
|
-
this
|
|
250
|
-
this
|
|
251
|
-
this
|
|
252
|
-
this
|
|
253
|
-
this
|
|
254
|
-
this
|
|
255
|
-
this
|
|
256
|
-
this
|
|
257
|
-
this
|
|
258
|
-
|
|
259
|
-
this.mongoLogger = this
|
|
214
|
+
this.poolState = PoolState.paused;
|
|
215
|
+
this.server = server;
|
|
216
|
+
this.connections = new List();
|
|
217
|
+
this.pending = 0;
|
|
218
|
+
this.checkedOut = new Set();
|
|
219
|
+
this.minPoolSizeTimer = undefined;
|
|
220
|
+
this.generation = 0;
|
|
221
|
+
this.serviceGenerations = new Map();
|
|
222
|
+
this.connectionCounter = makeCounter(1);
|
|
223
|
+
this.cancellationToken = new CancellationToken();
|
|
224
|
+
this.cancellationToken.setMaxListeners(Infinity);
|
|
225
|
+
this.waitQueue = new List();
|
|
226
|
+
this.metrics = new ConnectionPoolMetrics();
|
|
227
|
+
this.processingWaitQueue = false;
|
|
228
|
+
|
|
229
|
+
this.mongoLogger = this.server.topology.client?.mongoLogger;
|
|
260
230
|
this.component = 'connection';
|
|
261
231
|
|
|
262
232
|
process.nextTick(() => {
|
|
@@ -275,12 +245,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
275
245
|
* TODO(NODE-3263): We can remove this property once shell no longer needs it
|
|
276
246
|
*/
|
|
277
247
|
get closed(): boolean {
|
|
278
|
-
return this
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/** An integer representing the SDAM generation of the pool */
|
|
282
|
-
get generation(): number {
|
|
283
|
-
return this[kGeneration];
|
|
248
|
+
return this.poolState === PoolState.closed;
|
|
284
249
|
}
|
|
285
250
|
|
|
286
251
|
/** An integer expressing how many total connections (available + pending + in use) the pool currently has */
|
|
@@ -292,31 +257,27 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
292
257
|
|
|
293
258
|
/** An integer expressing how many connections are currently available in the pool. */
|
|
294
259
|
get availableConnectionCount(): number {
|
|
295
|
-
return this
|
|
260
|
+
return this.connections.length;
|
|
296
261
|
}
|
|
297
262
|
|
|
298
263
|
get pendingConnectionCount(): number {
|
|
299
|
-
return this
|
|
264
|
+
return this.pending;
|
|
300
265
|
}
|
|
301
266
|
|
|
302
267
|
get currentCheckedOutCount(): number {
|
|
303
|
-
return this
|
|
268
|
+
return this.checkedOut.size;
|
|
304
269
|
}
|
|
305
270
|
|
|
306
271
|
get waitQueueSize(): number {
|
|
307
|
-
return this
|
|
272
|
+
return this.waitQueue.length;
|
|
308
273
|
}
|
|
309
274
|
|
|
310
275
|
get loadBalanced(): boolean {
|
|
311
276
|
return this.options.loadBalanced;
|
|
312
277
|
}
|
|
313
278
|
|
|
314
|
-
get serviceGenerations(): Map<string, number> {
|
|
315
|
-
return this[kServiceGenerations];
|
|
316
|
-
}
|
|
317
|
-
|
|
318
279
|
get serverError() {
|
|
319
|
-
return this
|
|
280
|
+
return this.server.description.error;
|
|
320
281
|
}
|
|
321
282
|
|
|
322
283
|
/**
|
|
@@ -327,26 +288,26 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
327
288
|
* This property may be removed as a part of NODE-3263.
|
|
328
289
|
*/
|
|
329
290
|
get checkedOutConnections() {
|
|
330
|
-
return this
|
|
291
|
+
return this.checkedOut;
|
|
331
292
|
}
|
|
332
293
|
|
|
333
294
|
/**
|
|
334
295
|
* Get the metrics information for the pool when a wait queue timeout occurs.
|
|
335
296
|
*/
|
|
336
297
|
private waitQueueErrorMetrics(): string {
|
|
337
|
-
return this
|
|
298
|
+
return this.metrics.info(this.options.maxPoolSize);
|
|
338
299
|
}
|
|
339
300
|
|
|
340
301
|
/**
|
|
341
302
|
* Set the pool state to "ready"
|
|
342
303
|
*/
|
|
343
304
|
ready(): void {
|
|
344
|
-
if (this
|
|
305
|
+
if (this.poolState !== PoolState.paused) {
|
|
345
306
|
return;
|
|
346
307
|
}
|
|
347
|
-
this
|
|
308
|
+
this.poolState = PoolState.ready;
|
|
348
309
|
this.emitAndLog(ConnectionPool.CONNECTION_POOL_READY, new ConnectionPoolReadyEvent(this));
|
|
349
|
-
clearTimeout(this
|
|
310
|
+
clearTimeout(this.minPoolSizeTimer);
|
|
350
311
|
this.ensureMinPoolSize();
|
|
351
312
|
}
|
|
352
313
|
|
|
@@ -369,10 +330,11 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
369
330
|
const waitQueueMember: WaitQueueMember = {
|
|
370
331
|
resolve,
|
|
371
332
|
reject,
|
|
333
|
+
cancelled: false,
|
|
372
334
|
checkoutTime
|
|
373
335
|
};
|
|
374
336
|
|
|
375
|
-
this
|
|
337
|
+
this.waitQueue.push(waitQueueMember);
|
|
376
338
|
process.nextTick(() => this.processWaitQueue());
|
|
377
339
|
|
|
378
340
|
try {
|
|
@@ -381,7 +343,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
381
343
|
} catch (error) {
|
|
382
344
|
if (TimeoutError.is(error)) {
|
|
383
345
|
timeout?.clear();
|
|
384
|
-
waitQueueMember
|
|
346
|
+
waitQueueMember.cancelled = true;
|
|
385
347
|
|
|
386
348
|
this.emitAndLog(
|
|
387
349
|
ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
|
|
@@ -412,7 +374,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
412
374
|
* @param connection - The connection to check in
|
|
413
375
|
*/
|
|
414
376
|
checkIn(connection: Connection): void {
|
|
415
|
-
if (!this
|
|
377
|
+
if (!this.checkedOut.has(connection)) {
|
|
416
378
|
return;
|
|
417
379
|
}
|
|
418
380
|
const poolClosed = this.closed;
|
|
@@ -421,10 +383,10 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
421
383
|
|
|
422
384
|
if (!willDestroy) {
|
|
423
385
|
connection.markAvailable();
|
|
424
|
-
this
|
|
386
|
+
this.connections.unshift(connection);
|
|
425
387
|
}
|
|
426
388
|
|
|
427
|
-
this
|
|
389
|
+
this.checkedOut.delete(connection);
|
|
428
390
|
this.emitAndLog(
|
|
429
391
|
ConnectionPool.CONNECTION_CHECKED_IN,
|
|
430
392
|
new ConnectionCheckedInEvent(this, connection)
|
|
@@ -475,10 +437,10 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
475
437
|
}
|
|
476
438
|
// handle non load-balanced case
|
|
477
439
|
const interruptInUseConnections = options.interruptInUseConnections ?? false;
|
|
478
|
-
const oldGeneration = this
|
|
479
|
-
this
|
|
480
|
-
const alreadyPaused = this
|
|
481
|
-
this
|
|
440
|
+
const oldGeneration = this.generation;
|
|
441
|
+
this.generation += 1;
|
|
442
|
+
const alreadyPaused = this.poolState === PoolState.paused;
|
|
443
|
+
this.poolState = PoolState.paused;
|
|
482
444
|
|
|
483
445
|
this.clearMinPoolSizeTimer();
|
|
484
446
|
if (!alreadyPaused) {
|
|
@@ -503,7 +465,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
503
465
|
* Only connections where `connection.generation <= minGeneration` are killed.
|
|
504
466
|
*/
|
|
505
467
|
private interruptInUseConnections(minGeneration: number) {
|
|
506
|
-
for (const connection of this
|
|
468
|
+
for (const connection of this.checkedOut) {
|
|
507
469
|
if (connection.generation <= minGeneration) {
|
|
508
470
|
connection.onError(new PoolClearedOnNetworkError(this));
|
|
509
471
|
this.checkIn(connection);
|
|
@@ -518,25 +480,25 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
518
480
|
}
|
|
519
481
|
|
|
520
482
|
// immediately cancel any in-flight connections
|
|
521
|
-
this
|
|
483
|
+
this.cancellationToken.emit('cancel');
|
|
522
484
|
|
|
523
485
|
// end the connection counter
|
|
524
|
-
if (typeof this
|
|
525
|
-
this
|
|
486
|
+
if (typeof this.connectionCounter.return === 'function') {
|
|
487
|
+
this.connectionCounter.return(undefined);
|
|
526
488
|
}
|
|
527
489
|
|
|
528
|
-
this
|
|
490
|
+
this.poolState = PoolState.closed;
|
|
529
491
|
this.clearMinPoolSizeTimer();
|
|
530
492
|
this.processWaitQueue();
|
|
531
493
|
|
|
532
|
-
for (const conn of this
|
|
494
|
+
for (const conn of this.connections) {
|
|
533
495
|
this.emitAndLog(
|
|
534
496
|
ConnectionPool.CONNECTION_CLOSED,
|
|
535
497
|
new ConnectionClosedEvent(this, conn, 'poolClosed')
|
|
536
498
|
);
|
|
537
499
|
conn.destroy();
|
|
538
500
|
}
|
|
539
|
-
this
|
|
501
|
+
this.connections.clear();
|
|
540
502
|
this.emitAndLog(ConnectionPool.CONNECTION_POOL_CLOSED, new ConnectionPoolClosedEvent(this));
|
|
541
503
|
}
|
|
542
504
|
|
|
@@ -557,7 +519,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
557
519
|
}
|
|
558
520
|
|
|
559
521
|
const resolvedCredentials = credentials.resolveAuthMechanism(connection.hello);
|
|
560
|
-
const provider = this
|
|
522
|
+
const provider = this.server.topology.client.s.authProviders.getOrCreateProvider(
|
|
561
523
|
resolvedCredentials.mechanism,
|
|
562
524
|
resolvedCredentials.mechanismProperties
|
|
563
525
|
);
|
|
@@ -575,7 +537,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
575
537
|
|
|
576
538
|
/** Clear the min pool size timer */
|
|
577
539
|
private clearMinPoolSizeTimer(): void {
|
|
578
|
-
const minPoolSizeTimer = this
|
|
540
|
+
const minPoolSizeTimer = this.minPoolSizeTimer;
|
|
579
541
|
if (minPoolSizeTimer) {
|
|
580
542
|
clearTimeout(minPoolSizeTimer);
|
|
581
543
|
}
|
|
@@ -601,7 +563,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
601
563
|
return connection.generation !== generation;
|
|
602
564
|
}
|
|
603
565
|
|
|
604
|
-
return connection.generation !== this
|
|
566
|
+
return connection.generation !== this.generation;
|
|
605
567
|
}
|
|
606
568
|
|
|
607
569
|
private connectionIsIdle(connection: Connection) {
|
|
@@ -627,14 +589,14 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
627
589
|
private createConnection(callback: Callback<Connection>) {
|
|
628
590
|
const connectOptions: ConnectionOptions = {
|
|
629
591
|
...this.options,
|
|
630
|
-
id: this
|
|
631
|
-
generation: this
|
|
632
|
-
cancellationToken: this
|
|
592
|
+
id: this.connectionCounter.next().value,
|
|
593
|
+
generation: this.generation,
|
|
594
|
+
cancellationToken: this.cancellationToken,
|
|
633
595
|
mongoLogger: this.mongoLogger,
|
|
634
|
-
authProviders: this
|
|
596
|
+
authProviders: this.server.topology.client.s.authProviders
|
|
635
597
|
};
|
|
636
598
|
|
|
637
|
-
this
|
|
599
|
+
this.pending++;
|
|
638
600
|
// This is our version of a "virtual" no-I/O connection as the spec requires
|
|
639
601
|
const connectionCreatedTime = now();
|
|
640
602
|
this.emitAndLog(
|
|
@@ -645,8 +607,8 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
645
607
|
connect(connectOptions).then(
|
|
646
608
|
connection => {
|
|
647
609
|
// The pool might have closed since we started trying to create a connection
|
|
648
|
-
if (this
|
|
649
|
-
this
|
|
610
|
+
if (this.poolState !== PoolState.ready) {
|
|
611
|
+
this.pending--;
|
|
650
612
|
connection.destroy();
|
|
651
613
|
callback(this.closed ? new PoolClosedError(this) : new PoolClearedError(this));
|
|
652
614
|
return;
|
|
@@ -658,8 +620,8 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
658
620
|
}
|
|
659
621
|
|
|
660
622
|
if (this.loadBalanced) {
|
|
661
|
-
connection.on(Connection.PINNED, pinType => this
|
|
662
|
-
connection.on(Connection.UNPINNED, pinType => this
|
|
623
|
+
connection.on(Connection.PINNED, pinType => this.metrics.markPinned(pinType));
|
|
624
|
+
connection.on(Connection.UNPINNED, pinType => this.metrics.markUnpinned(pinType));
|
|
663
625
|
|
|
664
626
|
const serviceId = connection.serviceId;
|
|
665
627
|
if (serviceId) {
|
|
@@ -680,12 +642,12 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
680
642
|
new ConnectionReadyEvent(this, connection, connectionCreatedTime)
|
|
681
643
|
);
|
|
682
644
|
|
|
683
|
-
this
|
|
645
|
+
this.pending--;
|
|
684
646
|
callback(undefined, connection);
|
|
685
647
|
},
|
|
686
648
|
error => {
|
|
687
|
-
this
|
|
688
|
-
this
|
|
649
|
+
this.pending--;
|
|
650
|
+
this.server.handleError(error);
|
|
689
651
|
this.emitAndLog(
|
|
690
652
|
ConnectionPool.CONNECTION_CLOSED,
|
|
691
653
|
new ConnectionClosedEvent(
|
|
@@ -706,11 +668,11 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
706
668
|
|
|
707
669
|
private ensureMinPoolSize() {
|
|
708
670
|
const minPoolSize = this.options.minPoolSize;
|
|
709
|
-
if (this
|
|
671
|
+
if (this.poolState !== PoolState.ready || minPoolSize === 0) {
|
|
710
672
|
return;
|
|
711
673
|
}
|
|
712
674
|
|
|
713
|
-
this
|
|
675
|
+
this.connections.prune(connection => this.destroyConnectionIfPerished(connection));
|
|
714
676
|
|
|
715
677
|
if (
|
|
716
678
|
this.totalConnectionCount < minPoolSize &&
|
|
@@ -721,20 +683,20 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
721
683
|
// the connection to a checkout request
|
|
722
684
|
this.createConnection((err, connection) => {
|
|
723
685
|
if (!err && connection) {
|
|
724
|
-
this
|
|
686
|
+
this.connections.push(connection);
|
|
725
687
|
process.nextTick(() => this.processWaitQueue());
|
|
726
688
|
}
|
|
727
|
-
if (this
|
|
728
|
-
clearTimeout(this
|
|
729
|
-
this
|
|
689
|
+
if (this.poolState === PoolState.ready) {
|
|
690
|
+
clearTimeout(this.minPoolSizeTimer);
|
|
691
|
+
this.minPoolSizeTimer = setTimeout(
|
|
730
692
|
() => this.ensureMinPoolSize(),
|
|
731
693
|
this.options.minPoolSizeCheckFrequencyMS
|
|
732
694
|
);
|
|
733
695
|
}
|
|
734
696
|
});
|
|
735
697
|
} else {
|
|
736
|
-
clearTimeout(this
|
|
737
|
-
this
|
|
698
|
+
clearTimeout(this.minPoolSizeTimer);
|
|
699
|
+
this.minPoolSizeTimer = setTimeout(
|
|
738
700
|
() => this.ensureMinPoolSize(),
|
|
739
701
|
this.options.minPoolSizeCheckFrequencyMS
|
|
740
702
|
);
|
|
@@ -742,31 +704,31 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
742
704
|
}
|
|
743
705
|
|
|
744
706
|
private processWaitQueue() {
|
|
745
|
-
if (this
|
|
707
|
+
if (this.processingWaitQueue) {
|
|
746
708
|
return;
|
|
747
709
|
}
|
|
748
|
-
this
|
|
710
|
+
this.processingWaitQueue = true;
|
|
749
711
|
|
|
750
712
|
while (this.waitQueueSize) {
|
|
751
|
-
const waitQueueMember = this
|
|
713
|
+
const waitQueueMember = this.waitQueue.first();
|
|
752
714
|
if (!waitQueueMember) {
|
|
753
|
-
this
|
|
715
|
+
this.waitQueue.shift();
|
|
754
716
|
continue;
|
|
755
717
|
}
|
|
756
718
|
|
|
757
|
-
if (waitQueueMember
|
|
758
|
-
this
|
|
719
|
+
if (waitQueueMember.cancelled) {
|
|
720
|
+
this.waitQueue.shift();
|
|
759
721
|
continue;
|
|
760
722
|
}
|
|
761
723
|
|
|
762
|
-
if (this
|
|
724
|
+
if (this.poolState !== PoolState.ready) {
|
|
763
725
|
const reason = this.closed ? 'poolClosed' : 'connectionError';
|
|
764
726
|
const error = this.closed ? new PoolClosedError(this) : new PoolClearedError(this);
|
|
765
727
|
this.emitAndLog(
|
|
766
728
|
ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
|
|
767
729
|
new ConnectionCheckOutFailedEvent(this, reason, waitQueueMember.checkoutTime, error)
|
|
768
730
|
);
|
|
769
|
-
this
|
|
731
|
+
this.waitQueue.shift();
|
|
770
732
|
waitQueueMember.reject(error);
|
|
771
733
|
continue;
|
|
772
734
|
}
|
|
@@ -775,19 +737,19 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
775
737
|
break;
|
|
776
738
|
}
|
|
777
739
|
|
|
778
|
-
const connection = this
|
|
740
|
+
const connection = this.connections.shift();
|
|
779
741
|
if (!connection) {
|
|
780
742
|
break;
|
|
781
743
|
}
|
|
782
744
|
|
|
783
745
|
if (!this.destroyConnectionIfPerished(connection)) {
|
|
784
|
-
this
|
|
746
|
+
this.checkedOut.add(connection);
|
|
785
747
|
this.emitAndLog(
|
|
786
748
|
ConnectionPool.CONNECTION_CHECKED_OUT,
|
|
787
749
|
new ConnectionCheckedOutEvent(this, connection, waitQueueMember.checkoutTime)
|
|
788
750
|
);
|
|
789
751
|
|
|
790
|
-
this
|
|
752
|
+
this.waitQueue.shift();
|
|
791
753
|
waitQueueMember.resolve(connection);
|
|
792
754
|
}
|
|
793
755
|
}
|
|
@@ -798,14 +760,14 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
798
760
|
this.pendingConnectionCount < maxConnecting &&
|
|
799
761
|
(maxPoolSize === 0 || this.totalConnectionCount < maxPoolSize)
|
|
800
762
|
) {
|
|
801
|
-
const waitQueueMember = this
|
|
802
|
-
if (!waitQueueMember || waitQueueMember
|
|
763
|
+
const waitQueueMember = this.waitQueue.shift();
|
|
764
|
+
if (!waitQueueMember || waitQueueMember.cancelled) {
|
|
803
765
|
continue;
|
|
804
766
|
}
|
|
805
767
|
this.createConnection((err, connection) => {
|
|
806
|
-
if (waitQueueMember
|
|
768
|
+
if (waitQueueMember.cancelled) {
|
|
807
769
|
if (!err && connection) {
|
|
808
|
-
this
|
|
770
|
+
this.connections.push(connection);
|
|
809
771
|
}
|
|
810
772
|
} else {
|
|
811
773
|
if (err) {
|
|
@@ -821,7 +783,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
821
783
|
);
|
|
822
784
|
waitQueueMember.reject(err);
|
|
823
785
|
} else if (connection) {
|
|
824
|
-
this
|
|
786
|
+
this.checkedOut.add(connection);
|
|
825
787
|
this.emitAndLog(
|
|
826
788
|
ConnectionPool.CONNECTION_CHECKED_OUT,
|
|
827
789
|
new ConnectionCheckedOutEvent(this, connection, waitQueueMember.checkoutTime)
|
|
@@ -832,7 +794,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
|
|
|
832
794
|
process.nextTick(() => this.processWaitQueue());
|
|
833
795
|
});
|
|
834
796
|
}
|
|
835
|
-
this
|
|
797
|
+
this.processingWaitQueue = false;
|
|
836
798
|
}
|
|
837
799
|
}
|
|
838
800
|
|
package/src/encrypter.ts
CHANGED
|
@@ -7,9 +7,6 @@ import { MongoInvalidArgumentError, MongoMissingDependencyError } from './error'
|
|
|
7
7
|
import { MongoClient, type MongoClientOptions } from './mongo_client';
|
|
8
8
|
import { type Callback } from './utils';
|
|
9
9
|
|
|
10
|
-
/** @internal */
|
|
11
|
-
const kInternalClient = Symbol('internalClient');
|
|
12
|
-
|
|
13
10
|
/** @internal */
|
|
14
11
|
export interface EncrypterOptions {
|
|
15
12
|
autoEncryption: AutoEncryptionOptions;
|
|
@@ -18,7 +15,7 @@ export interface EncrypterOptions {
|
|
|
18
15
|
|
|
19
16
|
/** @internal */
|
|
20
17
|
export class Encrypter {
|
|
21
|
-
|
|
18
|
+
private internalClient: MongoClient | null;
|
|
22
19
|
bypassAutoEncryption: boolean;
|
|
23
20
|
needsConnecting: boolean;
|
|
24
21
|
autoEncrypter: AutoEncrypter;
|
|
@@ -28,7 +25,7 @@ export class Encrypter {
|
|
|
28
25
|
throw new MongoInvalidArgumentError('Option "autoEncryption" must be specified');
|
|
29
26
|
}
|
|
30
27
|
// initialize to null, if we call getInternalClient, we may set this it is important to not overwrite those function calls.
|
|
31
|
-
this
|
|
28
|
+
this.internalClient = null;
|
|
32
29
|
|
|
33
30
|
this.bypassAutoEncryption = !!options.autoEncryption.bypassAutoEncryption;
|
|
34
31
|
this.needsConnecting = false;
|
|
@@ -60,8 +57,7 @@ export class Encrypter {
|
|
|
60
57
|
}
|
|
61
58
|
|
|
62
59
|
getInternalClient(client: MongoClient, uri: string, options: MongoClientOptions): MongoClient {
|
|
63
|
-
|
|
64
|
-
let internalClient = this[kInternalClient];
|
|
60
|
+
let internalClient = this.internalClient;
|
|
65
61
|
if (internalClient == null) {
|
|
66
62
|
const clonedOptions: MongoClientOptions = {};
|
|
67
63
|
|
|
@@ -77,7 +73,7 @@ export class Encrypter {
|
|
|
77
73
|
clonedOptions.minPoolSize = 0;
|
|
78
74
|
|
|
79
75
|
internalClient = new MongoClient(uri, clonedOptions);
|
|
80
|
-
this
|
|
76
|
+
this.internalClient = internalClient;
|
|
81
77
|
|
|
82
78
|
for (const eventName of MONGO_CLIENT_EVENTS) {
|
|
83
79
|
for (const listener of client.listeners(eventName)) {
|
|
@@ -95,8 +91,7 @@ export class Encrypter {
|
|
|
95
91
|
}
|
|
96
92
|
|
|
97
93
|
async connectInternalClient(): Promise<void> {
|
|
98
|
-
|
|
99
|
-
const internalClient = this[kInternalClient];
|
|
94
|
+
const internalClient = this.internalClient;
|
|
100
95
|
if (this.needsConnecting && internalClient != null) {
|
|
101
96
|
this.needsConnecting = false;
|
|
102
97
|
await internalClient.connect();
|
|
@@ -114,7 +109,7 @@ export class Encrypter {
|
|
|
114
109
|
} catch (autoEncrypterError) {
|
|
115
110
|
error = autoEncrypterError;
|
|
116
111
|
}
|
|
117
|
-
const internalClient = this
|
|
112
|
+
const internalClient = this.internalClient;
|
|
118
113
|
if (internalClient != null && client !== internalClient) {
|
|
119
114
|
return await internalClient.close(force);
|
|
120
115
|
}
|