@@ -39,7 +39,9 @@ const kLogger = Symbol('logger');
39
39
/** @internal */
40
40
const kConnections = Symbol ( 'connections' ) ;
41
41
/** @internal */
42
- const kPermits = Symbol ( 'permits' ) ;
42
+ const kPending = Symbol ( 'pending' ) ;
43
+ /** @internal */
44
+ const kCheckedOut = Symbol ( 'checkedOut' ) ;
43
45
/** @internal */
44
46
const kMinPoolSizeTimer = Symbol ( 'minPoolSizeTimer' ) ;
45
47
/** @internal */
@@ -57,8 +59,6 @@ const kCancelled = Symbol('cancelled');
57
59
/** @internal */
58
60
const kMetrics = Symbol ( 'metrics' ) ;
59
61
/** @internal */
60
- const kCheckedOut = Symbol ( 'checkedOut' ) ;
61
- /** @internal */
62
62
const kProcessingWaitQueue = Symbol ( 'processingWaitQueue' ) ;
63
63
64
64
/** @public */
@@ -112,11 +112,10 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
112
112
[ kLogger ] : Logger ;
113
113
/** @internal */
114
114
[ kConnections ] : Denque < Connection > ;
115
- /**
116
- * An integer expressing how many total connections are permitted
117
- * @internal
118
- */
119
- [ kPermits ] : number ;
115
+ /** @internal */
116
+ [ kPending ] : number ;
117
+ /** @internal */
118
+ [ kCheckedOut ] : number ;
120
119
/** @internal */
121
120
[ kMinPoolSizeTimer ] ?: NodeJS . Timeout ;
122
121
/**
@@ -137,8 +136,6 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
137
136
/** @internal */
138
137
[ kMetrics ] : ConnectionPoolMetrics ;
139
138
/** @internal */
140
- [ kCheckedOut ] : number ;
141
- /** @internal */
142
139
[ kProcessingWaitQueue ] : boolean ;
143
140
144
141
/**
@@ -216,7 +213,8 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
216
213
217
214
this [ kLogger ] = new Logger ( 'ConnectionPool' ) ;
218
215
this [ kConnections ] = new Denque ( ) ;
219
- this [ kPermits ] = this . options . maxPoolSize ;
216
+ this [ kPending ] = 0 ;
217
+ this [ kCheckedOut ] = 0 ;
220
218
this [ kMinPoolSizeTimer ] = undefined ;
221
219
this [ kGeneration ] = 0 ;
222
220
this [ kServiceGenerations ] = new Map ( ) ;
@@ -225,7 +223,6 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
225
223
this [ kCancellationToken ] . setMaxListeners ( Infinity ) ;
226
224
this [ kWaitQueue ] = new Denque ( ) ;
227
225
this [ kMetrics ] = new ConnectionPoolMetrics ( ) ;
228
- this [ kCheckedOut ] = 0 ;
229
226
this [ kProcessingWaitQueue ] = false ;
230
227
231
228
process . nextTick ( ( ) => {
@@ -244,16 +241,26 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
244
241
return this [ kGeneration ] ;
245
242
}
246
243
247
- /** An integer expressing how many total connections (active + in use) the pool currently has */
244
+ /** An integer expressing how many total connections (available + pending + in use) the pool currently has */
248
245
get totalConnectionCount ( ) : number {
249
- return this [ kConnections ] . length + ( this . options . maxPoolSize - this [ kPermits ] ) ;
246
+ return (
247
+ this . availableConnectionCount + this . pendingConnectionCount + this . currentCheckedOutCount
248
+ ) ;
250
249
}
251
250
252
251
/** An integer expressing how many connections are currently available in the pool. */
253
252
get availableConnectionCount ( ) : number {
254
253
return this [ kConnections ] . length ;
255
254
}
256
255
256
+ get pendingConnectionCount ( ) : number {
257
+ return this [ kPending ] ;
258
+ }
259
+
260
+ get currentCheckedOutCount ( ) : number {
261
+ return this [ kCheckedOut ] ;
262
+ }
263
+
257
264
get waitQueueSize ( ) : number {
258
265
return this [ kWaitQueue ] . length ;
259
266
}
@@ -266,10 +273,6 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
266
273
return this [ kServiceGenerations ] ;
267
274
}
268
275
269
- get currentCheckedOutCount ( ) : number {
270
- return this [ kCheckedOut ] ;
271
- }
272
-
273
276
/**
274
277
* Get the metrics information for the pool when a wait queue timeout occurs.
275
278
*/
@@ -319,7 +322,6 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
319
322
} , waitQueueTimeoutMS ) ;
320
323
}
321
324
322
- this [ kCheckedOut ] = this [ kCheckedOut ] + 1 ;
323
325
this [ kWaitQueue ] . push ( waitQueueMember ) ;
324
326
process . nextTick ( processWaitQueue , this ) ;
325
327
}
@@ -339,7 +341,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
339
341
this [ kConnections ] . unshift ( connection ) ;
340
342
}
341
343
342
- this [ kCheckedOut ] = this [ kCheckedOut ] - 1 ;
344
+ this [ kCheckedOut ] -- ;
343
345
this . emit ( ConnectionPool . CONNECTION_CHECKED_IN , new ConnectionCheckedInEvent ( this , connection ) ) ;
344
346
345
347
if ( willDestroy ) {
@@ -527,10 +529,10 @@ function createConnection(pool: ConnectionPool, callback?: Callback<Connection>)
527
529
cancellationToken : pool [ kCancellationToken ]
528
530
} ;
529
531
530
- pool [ kPermits ] -- ;
532
+ pool [ kPending ] ++ ;
531
533
connect ( connectOptions , ( err , connection ) => {
532
534
if ( err || ! connection ) {
533
- pool [ kPermits ] ++ ;
535
+ pool [ kPending ] -- ;
534
536
pool [ kLogger ] . debug ( `connection attempt failed with error [${ JSON . stringify ( err ) } ]` ) ;
535
537
if ( typeof callback === 'function' ) {
536
538
callback ( err ) ;
@@ -541,6 +543,7 @@ function createConnection(pool: ConnectionPool, callback?: Callback<Connection>)
541
543
542
544
// The pool might have closed since we started trying to create a connection
543
545
if ( pool . closed ) {
546
+ pool [ kPending ] -- ;
544
547
connection . destroy ( { force : true } ) ;
545
548
return ;
546
549
}
@@ -572,24 +575,22 @@ function createConnection(pool: ConnectionPool, callback?: Callback<Connection>)
572
575
connection . markAvailable ( ) ;
573
576
pool . emit ( ConnectionPool . CONNECTION_READY , new ConnectionReadyEvent ( pool , connection ) ) ;
574
577
575
- // if a callback has been provided, check out the connection immediately
578
+ // if a callback has been provided, hand off the connection immediately
576
579
if ( typeof callback === 'function' ) {
577
580
callback ( undefined , connection ) ;
578
581
return ;
579
582
}
580
583
581
584
// otherwise add it to the pool for later acquisition, and try to process the wait queue
582
585
pool [ kConnections ] . push ( connection ) ;
586
+ pool [ kPending ] -- ;
583
587
process . nextTick ( processWaitQueue , pool ) ;
584
588
} ) ;
585
589
}
586
590
587
591
function destroyConnection ( pool : ConnectionPool , connection : Connection , reason : string ) {
588
592
pool . emit ( ConnectionPool . CONNECTION_CLOSED , new ConnectionClosedEvent ( pool , connection , reason ) ) ;
589
593
590
- // allow more connections to be created
591
- pool [ kPermits ] ++ ;
592
-
593
594
// destroy the connection
594
595
process . nextTick ( ( ) => connection . destroy ( ) ) ;
595
596
}
@@ -624,6 +625,7 @@ function processWaitQueue(pool: ConnectionPool) {
624
625
const isStale = connectionIsStale ( pool , connection ) ;
625
626
const isIdle = connectionIsIdle ( pool , connection ) ;
626
627
if ( ! isStale && ! isIdle && ! connection . closed ) {
628
+ pool [ kCheckedOut ] ++ ;
627
629
pool . emit (
628
630
ConnectionPool . CONNECTION_CHECKED_OUT ,
629
631
new ConnectionCheckedOutEvent ( pool , connection )
@@ -647,6 +649,7 @@ function processWaitQueue(pool: ConnectionPool) {
647
649
if ( ! waitQueueMember || waitQueueMember [ kCancelled ] ) {
648
650
if ( ! err && connection ) {
649
651
pool [ kConnections ] . push ( connection ) ;
652
+ pool [ kPending ] -- ;
650
653
}
651
654
652
655
pool [ kProcessingWaitQueue ] = false ;
@@ -659,6 +662,8 @@ function processWaitQueue(pool: ConnectionPool) {
659
662
new ConnectionCheckOutFailedEvent ( pool , err )
660
663
) ;
661
664
} else if ( connection ) {
665
+ pool [ kCheckedOut ] ++ ;
666
+ pool [ kPending ] -- ;
662
667
pool . emit (
663
668
ConnectionPool . CONNECTION_CHECKED_OUT ,
664
669
new ConnectionCheckedOutEvent ( pool , connection )
0 commit comments