mongodb 6.12.0 → 6.13.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.
Files changed (92) hide show
  1. package/lib/beta.d.ts +176 -108
  2. package/lib/bulk/common.js +5 -7
  3. package/lib/bulk/common.js.map +1 -1
  4. package/lib/change_stream.js +16 -26
  5. package/lib/change_stream.js.map +1 -1
  6. package/lib/client-side-encryption/auto_encrypter.js +4 -2
  7. package/lib/client-side-encryption/auto_encrypter.js.map +1 -1
  8. package/lib/client-side-encryption/client_encryption.js +4 -4
  9. package/lib/client-side-encryption/client_encryption.js.map +1 -1
  10. package/lib/client-side-encryption/state_machine.js +56 -30
  11. package/lib/client-side-encryption/state_machine.js.map +1 -1
  12. package/lib/cmap/auth/mongodb_oidc.js +1 -1
  13. package/lib/cmap/auth/mongodb_oidc.js.map +1 -1
  14. package/lib/cmap/command_monitoring_events.js +9 -50
  15. package/lib/cmap/command_monitoring_events.js.map +1 -1
  16. package/lib/cmap/connection.js +28 -22
  17. package/lib/cmap/connection.js.map +1 -1
  18. package/lib/cmap/connection_pool.js +88 -117
  19. package/lib/cmap/connection_pool.js.map +1 -1
  20. package/lib/cmap/wire_protocol/on_data.js +6 -1
  21. package/lib/cmap/wire_protocol/on_data.js.map +1 -1
  22. package/lib/collection.js.map +1 -1
  23. package/lib/connection_string.js +68 -86
  24. package/lib/connection_string.js.map +1 -1
  25. package/lib/cursor/abstract_cursor.js +47 -18
  26. package/lib/cursor/abstract_cursor.js.map +1 -1
  27. package/lib/cursor/aggregation_cursor.js +2 -1
  28. package/lib/cursor/aggregation_cursor.js.map +1 -1
  29. package/lib/cursor/find_cursor.js +2 -1
  30. package/lib/cursor/find_cursor.js.map +1 -1
  31. package/lib/cursor/list_collections_cursor.js +2 -1
  32. package/lib/cursor/list_collections_cursor.js.map +1 -1
  33. package/lib/db.js +2 -1
  34. package/lib/db.js.map +1 -1
  35. package/lib/encrypter.js +5 -9
  36. package/lib/encrypter.js.map +1 -1
  37. package/lib/error.js +10 -18
  38. package/lib/error.js.map +1 -1
  39. package/lib/index.js +5 -2
  40. package/lib/index.js.map +1 -1
  41. package/lib/mongo_client.js +46 -26
  42. package/lib/mongo_client.js.map +1 -1
  43. package/lib/mongo_logger.js +102 -3
  44. package/lib/mongo_logger.js.map +1 -1
  45. package/lib/operations/execute_operation.js +9 -5
  46. package/lib/operations/execute_operation.js.map +1 -1
  47. package/lib/operations/list_collections.js.map +1 -1
  48. package/lib/operations/operation.js +4 -5
  49. package/lib/operations/operation.js.map +1 -1
  50. package/lib/sdam/monitor.js +25 -31
  51. package/lib/sdam/monitor.js.map +1 -1
  52. package/lib/sdam/server.js +27 -17
  53. package/lib/sdam/server.js.map +1 -1
  54. package/lib/sdam/topology.js +20 -19
  55. package/lib/sdam/topology.js.map +1 -1
  56. package/lib/sessions.js +24 -48
  57. package/lib/sessions.js.map +1 -1
  58. package/lib/utils.js +64 -44
  59. package/lib/utils.js.map +1 -1
  60. package/mongodb.d.ts +176 -108
  61. package/package.json +1 -1
  62. package/src/bulk/common.ts +6 -9
  63. package/src/change_stream.ts +21 -33
  64. package/src/client-side-encryption/auto_encrypter.ts +12 -8
  65. package/src/client-side-encryption/client_encryption.ts +6 -4
  66. package/src/client-side-encryption/state_machine.ts +80 -36
  67. package/src/cmap/auth/mongodb_oidc.ts +1 -1
  68. package/src/cmap/command_monitoring_events.ts +10 -55
  69. package/src/cmap/connection.ts +37 -29
  70. package/src/cmap/connection_pool.ts +121 -145
  71. package/src/cmap/wire_protocol/on_data.ts +9 -2
  72. package/src/collection.ts +15 -8
  73. package/src/connection_string.ts +74 -99
  74. package/src/cursor/abstract_cursor.ts +71 -23
  75. package/src/cursor/aggregation_cursor.ts +5 -3
  76. package/src/cursor/find_cursor.ts +5 -3
  77. package/src/cursor/list_collections_cursor.ts +5 -3
  78. package/src/db.ts +11 -7
  79. package/src/encrypter.ts +6 -11
  80. package/src/error.ts +11 -23
  81. package/src/index.ts +3 -3
  82. package/src/mongo_client.ts +78 -47
  83. package/src/mongo_logger.ts +158 -11
  84. package/src/mongo_types.ts +38 -0
  85. package/src/operations/execute_operation.ts +11 -6
  86. package/src/operations/list_collections.ts +4 -1
  87. package/src/operations/operation.ts +8 -9
  88. package/src/sdam/monitor.ts +30 -38
  89. package/src/sdam/server.ts +33 -20
  90. package/src/sdam/topology.ts +29 -26
  91. package/src/sessions.ts +37 -58
  92. package/src/utils.ts +79 -43
@@ -25,10 +25,18 @@ import {
25
25
  MongoRuntimeError,
26
26
  MongoServerError
27
27
  } from '../error';
28
- import { CancellationToken, TypedEventEmitter } from '../mongo_types';
28
+ import { type Abortable, CancellationToken, TypedEventEmitter } from '../mongo_types';
29
29
  import type { Server } from '../sdam/server';
30
30
  import { type TimeoutContext, TimeoutError } from '../timeout';
31
- import { type Callback, List, makeCounter, now, promiseWithResolvers } from '../utils';
31
+ import {
32
+ addAbortListener,
33
+ type Callback,
34
+ kDispose,
35
+ List,
36
+ makeCounter,
37
+ now,
38
+ promiseWithResolvers
39
+ } from '../utils';
32
40
  import { connect } from './connect';
33
41
  import { Connection, type ConnectionEvents, type ConnectionOptions } from './connection';
34
42
  import {
@@ -52,35 +60,6 @@ import {
52
60
  } from './errors';
53
61
  import { ConnectionPoolMetrics } from './metrics';
54
62
 
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
63
  /** @public */
85
64
  export interface ConnectionPoolOptions extends Omit<ConnectionOptions, 'id' | 'generation'> {
86
65
  /** 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 +82,7 @@ export interface ConnectionPoolOptions extends Omit<ConnectionOptions, 'id' | 'g
103
82
  export interface WaitQueueMember {
104
83
  resolve: (conn: Connection) => void;
105
84
  reject: (err: AnyError) => void;
106
- [kCancelled]?: boolean;
85
+ cancelled: boolean;
107
86
  checkoutTime: number;
108
87
  }
109
88
 
@@ -114,6 +93,8 @@ export const PoolState = Object.freeze({
114
93
  closed: 'closed'
115
94
  } as const);
116
95
 
96
+ type PoolState = (typeof PoolState)[keyof typeof PoolState];
97
+
117
98
  /**
118
99
  * @public
119
100
  * @deprecated This interface is deprecated and will be removed in a future release as it is not used
@@ -143,26 +124,23 @@ export type ConnectionPoolEvents = {
143
124
  * @internal
144
125
  */
145
126
  export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
146
- options: Readonly<ConnectionPoolOptions>;
147
- [kPoolState]: (typeof PoolState)[keyof typeof PoolState];
148
- [kServer]: Server;
149
- [kConnections]: List<Connection>;
150
- [kPending]: number;
151
- [kCheckedOut]: Set<Connection>;
152
- [kMinPoolSizeTimer]?: NodeJS.Timeout;
153
- /**
154
- * An integer representing the SDAM generation of the pool
155
- */
156
- [kGeneration]: number;
157
- /**
158
- * A map of generations to service ids
159
- */
160
- [kServiceGenerations]: Map<string, number>;
161
- [kConnectionCounter]: Generator<number>;
162
- [kCancellationToken]: CancellationToken;
163
- [kWaitQueue]: List<WaitQueueMember>;
164
- [kMetrics]: ConnectionPoolMetrics;
165
- [kProcessingWaitQueue]: boolean;
127
+ public options: Readonly<ConnectionPoolOptions>;
128
+ /** An integer representing the SDAM generation of the pool */
129
+ public generation: number;
130
+ /** A map of generations to service ids */
131
+ public serviceGenerations: Map<string, number>;
132
+
133
+ private poolState: PoolState;
134
+ private server: Server;
135
+ private connections: List<Connection>;
136
+ private pending: number;
137
+ private checkedOut: Set<Connection>;
138
+ private minPoolSizeTimer?: NodeJS.Timeout;
139
+ private connectionCounter: Generator<number>;
140
+ private cancellationToken: CancellationToken;
141
+ private waitQueue: List<WaitQueueMember>;
142
+ private metrics: ConnectionPoolMetrics;
143
+ private processingWaitQueue: boolean;
166
144
 
167
145
  /**
168
146
  * Emitted when the connection pool is created.
@@ -241,22 +219,22 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
241
219
  );
242
220
  }
243
221
 
244
- this[kPoolState] = PoolState.paused;
245
- this[kServer] = server;
246
- this[kConnections] = new List();
247
- this[kPending] = 0;
248
- this[kCheckedOut] = new Set();
249
- this[kMinPoolSizeTimer] = undefined;
250
- this[kGeneration] = 0;
251
- this[kServiceGenerations] = new Map();
252
- this[kConnectionCounter] = makeCounter(1);
253
- this[kCancellationToken] = new CancellationToken();
254
- this[kCancellationToken].setMaxListeners(Infinity);
255
- this[kWaitQueue] = new List();
256
- this[kMetrics] = new ConnectionPoolMetrics();
257
- this[kProcessingWaitQueue] = false;
258
-
259
- this.mongoLogger = this[kServer].topology.client?.mongoLogger;
222
+ this.poolState = PoolState.paused;
223
+ this.server = server;
224
+ this.connections = new List();
225
+ this.pending = 0;
226
+ this.checkedOut = new Set();
227
+ this.minPoolSizeTimer = undefined;
228
+ this.generation = 0;
229
+ this.serviceGenerations = new Map();
230
+ this.connectionCounter = makeCounter(1);
231
+ this.cancellationToken = new CancellationToken();
232
+ this.cancellationToken.setMaxListeners(Infinity);
233
+ this.waitQueue = new List();
234
+ this.metrics = new ConnectionPoolMetrics();
235
+ this.processingWaitQueue = false;
236
+
237
+ this.mongoLogger = this.server.topology.client?.mongoLogger;
260
238
  this.component = 'connection';
261
239
 
262
240
  process.nextTick(() => {
@@ -275,12 +253,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
275
253
  * TODO(NODE-3263): We can remove this property once shell no longer needs it
276
254
  */
277
255
  get closed(): boolean {
278
- return this[kPoolState] === PoolState.closed;
279
- }
280
-
281
- /** An integer representing the SDAM generation of the pool */
282
- get generation(): number {
283
- return this[kGeneration];
256
+ return this.poolState === PoolState.closed;
284
257
  }
285
258
 
286
259
  /** An integer expressing how many total connections (available + pending + in use) the pool currently has */
@@ -292,31 +265,27 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
292
265
 
293
266
  /** An integer expressing how many connections are currently available in the pool. */
294
267
  get availableConnectionCount(): number {
295
- return this[kConnections].length;
268
+ return this.connections.length;
296
269
  }
297
270
 
298
271
  get pendingConnectionCount(): number {
299
- return this[kPending];
272
+ return this.pending;
300
273
  }
301
274
 
302
275
  get currentCheckedOutCount(): number {
303
- return this[kCheckedOut].size;
276
+ return this.checkedOut.size;
304
277
  }
305
278
 
306
279
  get waitQueueSize(): number {
307
- return this[kWaitQueue].length;
280
+ return this.waitQueue.length;
308
281
  }
309
282
 
310
283
  get loadBalanced(): boolean {
311
284
  return this.options.loadBalanced;
312
285
  }
313
286
 
314
- get serviceGenerations(): Map<string, number> {
315
- return this[kServiceGenerations];
316
- }
317
-
318
287
  get serverError() {
319
- return this[kServer].description.error;
288
+ return this.server.description.error;
320
289
  }
321
290
 
322
291
  /**
@@ -327,26 +296,26 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
327
296
  * This property may be removed as a part of NODE-3263.
328
297
  */
329
298
  get checkedOutConnections() {
330
- return this[kCheckedOut];
299
+ return this.checkedOut;
331
300
  }
332
301
 
333
302
  /**
334
303
  * Get the metrics information for the pool when a wait queue timeout occurs.
335
304
  */
336
305
  private waitQueueErrorMetrics(): string {
337
- return this[kMetrics].info(this.options.maxPoolSize);
306
+ return this.metrics.info(this.options.maxPoolSize);
338
307
  }
339
308
 
340
309
  /**
341
310
  * Set the pool state to "ready"
342
311
  */
343
312
  ready(): void {
344
- if (this[kPoolState] !== PoolState.paused) {
313
+ if (this.poolState !== PoolState.paused) {
345
314
  return;
346
315
  }
347
- this[kPoolState] = PoolState.ready;
316
+ this.poolState = PoolState.ready;
348
317
  this.emitAndLog(ConnectionPool.CONNECTION_POOL_READY, new ConnectionPoolReadyEvent(this));
349
- clearTimeout(this[kMinPoolSizeTimer]);
318
+ clearTimeout(this.minPoolSizeTimer);
350
319
  this.ensureMinPoolSize();
351
320
  }
352
321
 
@@ -355,7 +324,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
355
324
  * will be held by the pool. This means that if a connection is checked out it MUST be checked back in or
356
325
  * explicitly destroyed by the new owner.
357
326
  */
358
- async checkOut(options: { timeoutContext: TimeoutContext }): Promise<Connection> {
327
+ async checkOut(options: { timeoutContext: TimeoutContext } & Abortable): Promise<Connection> {
359
328
  const checkoutTime = now();
360
329
  this.emitAndLog(
361
330
  ConnectionPool.CONNECTION_CHECK_OUT_STARTED,
@@ -369,10 +338,16 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
369
338
  const waitQueueMember: WaitQueueMember = {
370
339
  resolve,
371
340
  reject,
341
+ cancelled: false,
372
342
  checkoutTime
373
343
  };
374
344
 
375
- this[kWaitQueue].push(waitQueueMember);
345
+ const abortListener = addAbortListener(options.signal, function () {
346
+ waitQueueMember.cancelled = true;
347
+ reject(this.reason);
348
+ });
349
+
350
+ this.waitQueue.push(waitQueueMember);
376
351
  process.nextTick(() => this.processWaitQueue());
377
352
 
378
353
  try {
@@ -381,7 +356,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
381
356
  } catch (error) {
382
357
  if (TimeoutError.is(error)) {
383
358
  timeout?.clear();
384
- waitQueueMember[kCancelled] = true;
359
+ waitQueueMember.cancelled = true;
385
360
 
386
361
  this.emitAndLog(
387
362
  ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
@@ -402,6 +377,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
402
377
  }
403
378
  throw error;
404
379
  } finally {
380
+ abortListener?.[kDispose]();
405
381
  timeout?.clear();
406
382
  }
407
383
  }
@@ -412,7 +388,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
412
388
  * @param connection - The connection to check in
413
389
  */
414
390
  checkIn(connection: Connection): void {
415
- if (!this[kCheckedOut].has(connection)) {
391
+ if (!this.checkedOut.has(connection)) {
416
392
  return;
417
393
  }
418
394
  const poolClosed = this.closed;
@@ -421,10 +397,10 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
421
397
 
422
398
  if (!willDestroy) {
423
399
  connection.markAvailable();
424
- this[kConnections].unshift(connection);
400
+ this.connections.unshift(connection);
425
401
  }
426
402
 
427
- this[kCheckedOut].delete(connection);
403
+ this.checkedOut.delete(connection);
428
404
  this.emitAndLog(
429
405
  ConnectionPool.CONNECTION_CHECKED_IN,
430
406
  new ConnectionCheckedInEvent(this, connection)
@@ -475,10 +451,10 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
475
451
  }
476
452
  // handle non load-balanced case
477
453
  const interruptInUseConnections = options.interruptInUseConnections ?? false;
478
- const oldGeneration = this[kGeneration];
479
- this[kGeneration] += 1;
480
- const alreadyPaused = this[kPoolState] === PoolState.paused;
481
- this[kPoolState] = PoolState.paused;
454
+ const oldGeneration = this.generation;
455
+ this.generation += 1;
456
+ const alreadyPaused = this.poolState === PoolState.paused;
457
+ this.poolState = PoolState.paused;
482
458
 
483
459
  this.clearMinPoolSizeTimer();
484
460
  if (!alreadyPaused) {
@@ -503,7 +479,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
503
479
  * Only connections where `connection.generation <= minGeneration` are killed.
504
480
  */
505
481
  private interruptInUseConnections(minGeneration: number) {
506
- for (const connection of this[kCheckedOut]) {
482
+ for (const connection of this.checkedOut) {
507
483
  if (connection.generation <= minGeneration) {
508
484
  connection.onError(new PoolClearedOnNetworkError(this));
509
485
  this.checkIn(connection);
@@ -518,25 +494,25 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
518
494
  }
519
495
 
520
496
  // immediately cancel any in-flight connections
521
- this[kCancellationToken].emit('cancel');
497
+ this.cancellationToken.emit('cancel');
522
498
 
523
499
  // end the connection counter
524
- if (typeof this[kConnectionCounter].return === 'function') {
525
- this[kConnectionCounter].return(undefined);
500
+ if (typeof this.connectionCounter.return === 'function') {
501
+ this.connectionCounter.return(undefined);
526
502
  }
527
503
 
528
- this[kPoolState] = PoolState.closed;
504
+ this.poolState = PoolState.closed;
529
505
  this.clearMinPoolSizeTimer();
530
506
  this.processWaitQueue();
531
507
 
532
- for (const conn of this[kConnections]) {
508
+ for (const conn of this.connections) {
533
509
  this.emitAndLog(
534
510
  ConnectionPool.CONNECTION_CLOSED,
535
511
  new ConnectionClosedEvent(this, conn, 'poolClosed')
536
512
  );
537
513
  conn.destroy();
538
514
  }
539
- this[kConnections].clear();
515
+ this.connections.clear();
540
516
  this.emitAndLog(ConnectionPool.CONNECTION_POOL_CLOSED, new ConnectionPoolClosedEvent(this));
541
517
  }
542
518
 
@@ -557,7 +533,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
557
533
  }
558
534
 
559
535
  const resolvedCredentials = credentials.resolveAuthMechanism(connection.hello);
560
- const provider = this[kServer].topology.client.s.authProviders.getOrCreateProvider(
536
+ const provider = this.server.topology.client.s.authProviders.getOrCreateProvider(
561
537
  resolvedCredentials.mechanism,
562
538
  resolvedCredentials.mechanismProperties
563
539
  );
@@ -575,7 +551,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
575
551
 
576
552
  /** Clear the min pool size timer */
577
553
  private clearMinPoolSizeTimer(): void {
578
- const minPoolSizeTimer = this[kMinPoolSizeTimer];
554
+ const minPoolSizeTimer = this.minPoolSizeTimer;
579
555
  if (minPoolSizeTimer) {
580
556
  clearTimeout(minPoolSizeTimer);
581
557
  }
@@ -601,7 +577,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
601
577
  return connection.generation !== generation;
602
578
  }
603
579
 
604
- return connection.generation !== this[kGeneration];
580
+ return connection.generation !== this.generation;
605
581
  }
606
582
 
607
583
  private connectionIsIdle(connection: Connection) {
@@ -627,14 +603,14 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
627
603
  private createConnection(callback: Callback<Connection>) {
628
604
  const connectOptions: ConnectionOptions = {
629
605
  ...this.options,
630
- id: this[kConnectionCounter].next().value,
631
- generation: this[kGeneration],
632
- cancellationToken: this[kCancellationToken],
606
+ id: this.connectionCounter.next().value,
607
+ generation: this.generation,
608
+ cancellationToken: this.cancellationToken,
633
609
  mongoLogger: this.mongoLogger,
634
- authProviders: this[kServer].topology.client.s.authProviders
610
+ authProviders: this.server.topology.client.s.authProviders
635
611
  };
636
612
 
637
- this[kPending]++;
613
+ this.pending++;
638
614
  // This is our version of a "virtual" no-I/O connection as the spec requires
639
615
  const connectionCreatedTime = now();
640
616
  this.emitAndLog(
@@ -645,8 +621,8 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
645
621
  connect(connectOptions).then(
646
622
  connection => {
647
623
  // The pool might have closed since we started trying to create a connection
648
- if (this[kPoolState] !== PoolState.ready) {
649
- this[kPending]--;
624
+ if (this.poolState !== PoolState.ready) {
625
+ this.pending--;
650
626
  connection.destroy();
651
627
  callback(this.closed ? new PoolClosedError(this) : new PoolClearedError(this));
652
628
  return;
@@ -658,8 +634,8 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
658
634
  }
659
635
 
660
636
  if (this.loadBalanced) {
661
- connection.on(Connection.PINNED, pinType => this[kMetrics].markPinned(pinType));
662
- connection.on(Connection.UNPINNED, pinType => this[kMetrics].markUnpinned(pinType));
637
+ connection.on(Connection.PINNED, pinType => this.metrics.markPinned(pinType));
638
+ connection.on(Connection.UNPINNED, pinType => this.metrics.markUnpinned(pinType));
663
639
 
664
640
  const serviceId = connection.serviceId;
665
641
  if (serviceId) {
@@ -680,12 +656,12 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
680
656
  new ConnectionReadyEvent(this, connection, connectionCreatedTime)
681
657
  );
682
658
 
683
- this[kPending]--;
659
+ this.pending--;
684
660
  callback(undefined, connection);
685
661
  },
686
662
  error => {
687
- this[kPending]--;
688
- this[kServer].handleError(error);
663
+ this.pending--;
664
+ this.server.handleError(error);
689
665
  this.emitAndLog(
690
666
  ConnectionPool.CONNECTION_CLOSED,
691
667
  new ConnectionClosedEvent(
@@ -706,11 +682,11 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
706
682
 
707
683
  private ensureMinPoolSize() {
708
684
  const minPoolSize = this.options.minPoolSize;
709
- if (this[kPoolState] !== PoolState.ready || minPoolSize === 0) {
685
+ if (this.poolState !== PoolState.ready || minPoolSize === 0) {
710
686
  return;
711
687
  }
712
688
 
713
- this[kConnections].prune(connection => this.destroyConnectionIfPerished(connection));
689
+ this.connections.prune(connection => this.destroyConnectionIfPerished(connection));
714
690
 
715
691
  if (
716
692
  this.totalConnectionCount < minPoolSize &&
@@ -721,20 +697,20 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
721
697
  // the connection to a checkout request
722
698
  this.createConnection((err, connection) => {
723
699
  if (!err && connection) {
724
- this[kConnections].push(connection);
700
+ this.connections.push(connection);
725
701
  process.nextTick(() => this.processWaitQueue());
726
702
  }
727
- if (this[kPoolState] === PoolState.ready) {
728
- clearTimeout(this[kMinPoolSizeTimer]);
729
- this[kMinPoolSizeTimer] = setTimeout(
703
+ if (this.poolState === PoolState.ready) {
704
+ clearTimeout(this.minPoolSizeTimer);
705
+ this.minPoolSizeTimer = setTimeout(
730
706
  () => this.ensureMinPoolSize(),
731
707
  this.options.minPoolSizeCheckFrequencyMS
732
708
  );
733
709
  }
734
710
  });
735
711
  } else {
736
- clearTimeout(this[kMinPoolSizeTimer]);
737
- this[kMinPoolSizeTimer] = setTimeout(
712
+ clearTimeout(this.minPoolSizeTimer);
713
+ this.minPoolSizeTimer = setTimeout(
738
714
  () => this.ensureMinPoolSize(),
739
715
  this.options.minPoolSizeCheckFrequencyMS
740
716
  );
@@ -742,31 +718,31 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
742
718
  }
743
719
 
744
720
  private processWaitQueue() {
745
- if (this[kProcessingWaitQueue]) {
721
+ if (this.processingWaitQueue) {
746
722
  return;
747
723
  }
748
- this[kProcessingWaitQueue] = true;
724
+ this.processingWaitQueue = true;
749
725
 
750
726
  while (this.waitQueueSize) {
751
- const waitQueueMember = this[kWaitQueue].first();
727
+ const waitQueueMember = this.waitQueue.first();
752
728
  if (!waitQueueMember) {
753
- this[kWaitQueue].shift();
729
+ this.waitQueue.shift();
754
730
  continue;
755
731
  }
756
732
 
757
- if (waitQueueMember[kCancelled]) {
758
- this[kWaitQueue].shift();
733
+ if (waitQueueMember.cancelled) {
734
+ this.waitQueue.shift();
759
735
  continue;
760
736
  }
761
737
 
762
- if (this[kPoolState] !== PoolState.ready) {
738
+ if (this.poolState !== PoolState.ready) {
763
739
  const reason = this.closed ? 'poolClosed' : 'connectionError';
764
740
  const error = this.closed ? new PoolClosedError(this) : new PoolClearedError(this);
765
741
  this.emitAndLog(
766
742
  ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
767
743
  new ConnectionCheckOutFailedEvent(this, reason, waitQueueMember.checkoutTime, error)
768
744
  );
769
- this[kWaitQueue].shift();
745
+ this.waitQueue.shift();
770
746
  waitQueueMember.reject(error);
771
747
  continue;
772
748
  }
@@ -775,19 +751,19 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
775
751
  break;
776
752
  }
777
753
 
778
- const connection = this[kConnections].shift();
754
+ const connection = this.connections.shift();
779
755
  if (!connection) {
780
756
  break;
781
757
  }
782
758
 
783
759
  if (!this.destroyConnectionIfPerished(connection)) {
784
- this[kCheckedOut].add(connection);
760
+ this.checkedOut.add(connection);
785
761
  this.emitAndLog(
786
762
  ConnectionPool.CONNECTION_CHECKED_OUT,
787
763
  new ConnectionCheckedOutEvent(this, connection, waitQueueMember.checkoutTime)
788
764
  );
789
765
 
790
- this[kWaitQueue].shift();
766
+ this.waitQueue.shift();
791
767
  waitQueueMember.resolve(connection);
792
768
  }
793
769
  }
@@ -798,14 +774,14 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
798
774
  this.pendingConnectionCount < maxConnecting &&
799
775
  (maxPoolSize === 0 || this.totalConnectionCount < maxPoolSize)
800
776
  ) {
801
- const waitQueueMember = this[kWaitQueue].shift();
802
- if (!waitQueueMember || waitQueueMember[kCancelled]) {
777
+ const waitQueueMember = this.waitQueue.shift();
778
+ if (!waitQueueMember || waitQueueMember.cancelled) {
803
779
  continue;
804
780
  }
805
781
  this.createConnection((err, connection) => {
806
- if (waitQueueMember[kCancelled]) {
782
+ if (waitQueueMember.cancelled) {
807
783
  if (!err && connection) {
808
- this[kConnections].push(connection);
784
+ this.connections.push(connection);
809
785
  }
810
786
  } else {
811
787
  if (err) {
@@ -821,7 +797,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
821
797
  );
822
798
  waitQueueMember.reject(err);
823
799
  } else if (connection) {
824
- this[kCheckedOut].add(connection);
800
+ this.checkedOut.add(connection);
825
801
  this.emitAndLog(
826
802
  ConnectionPool.CONNECTION_CHECKED_OUT,
827
803
  new ConnectionCheckedOutEvent(this, connection, waitQueueMember.checkoutTime)
@@ -832,7 +808,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
832
808
  process.nextTick(() => this.processWaitQueue());
833
809
  });
834
810
  }
835
- this[kProcessingWaitQueue] = false;
811
+ this.processingWaitQueue = false;
836
812
  }
837
813
  }
838
814
 
@@ -1,7 +1,8 @@
1
1
  import { type EventEmitter } from 'events';
2
2
 
3
+ import { type Abortable } from '../../mongo_types';
3
4
  import { type TimeoutContext } from '../../timeout';
4
- import { List, promiseWithResolvers } from '../../utils';
5
+ import { addAbortListener, kDispose, List, promiseWithResolvers } from '../../utils';
5
6
 
6
7
  /**
7
8
  * @internal
@@ -21,8 +22,10 @@ type PendingPromises = Omit<
21
22
  */
22
23
  export function onData(
23
24
  emitter: EventEmitter,
24
- { timeoutContext }: { timeoutContext?: TimeoutContext }
25
+ { timeoutContext, signal }: { timeoutContext?: TimeoutContext } & Abortable
25
26
  ) {
27
+ signal?.throwIfAborted();
28
+
26
29
  // Setup pending events and pending promise lists
27
30
  /**
28
31
  * When the caller has not yet called .next(), we store the
@@ -90,6 +93,9 @@ export function onData(
90
93
  // Adding event handlers
91
94
  emitter.on('data', eventHandler);
92
95
  emitter.on('error', errorHandler);
96
+ const abortListener = addAbortListener(signal, function () {
97
+ errorHandler(this.reason);
98
+ });
93
99
 
94
100
  const timeoutForSocketRead = timeoutContext?.timeoutForSocketRead;
95
101
  timeoutForSocketRead?.throwIfExpired();
@@ -115,6 +121,7 @@ export function onData(
115
121
  // Adding event handlers
116
122
  emitter.off('data', eventHandler);
117
123
  emitter.off('error', errorHandler);
124
+ abortListener?.[kDispose]();
118
125
  finished = true;
119
126
  timeoutForSocketRead?.clear();
120
127
  const doneResult = { value: undefined, done: finished } as const;