@@ -21,8 +21,8 @@ class Pool extends EventEmitter {
2121 #requestTimeoutId;
2222 #connErrorNumber = 0 ;
2323 #initialized = false ;
24- _managePoolSizeTask ;
25- _connectionCreationTask ;
24+ #managePoolSizeTask ;
25+ #connectionCreationTask ;
2626
2727 constructor ( options ) {
2828 super ( ) ;
@@ -42,7 +42,7 @@ class Pool extends EventEmitter {
4242 */
4343 _managePoolSize ( ) {
4444 // Only create new connections if conditions are met and no creation is in progress
45- if ( ! this . _shouldCreateMoreConnections ( ) || this . _managePoolSizeTask ) {
45+ if ( ! this . _shouldCreateMoreConnections ( ) || this . #managePoolSizeTask ) {
4646 return ;
4747 }
4848
@@ -73,7 +73,7 @@ class Pool extends EventEmitter {
7373 this . #initialized = true ;
7474 this . #errorCreatingConnection = null ;
7575 this . #connErrorNumber = 0 ;
76- this . _connectionCreationTask = null ;
76+ this . #connectionCreationTask = null ;
7777
7878 // Check if we need more connections
7979 if ( this . _shouldCreateMoreConnections ( ) ) {
@@ -138,8 +138,8 @@ class Pool extends EventEmitter {
138138 if ( this . #closed) {
139139 return ;
140140 }
141- this . _managePoolSizeTask = setTimeout ( ( ) => {
142- this . _managePoolSizeTask = null ;
141+ this . #managePoolSizeTask = setTimeout ( ( ) => {
142+ this . #managePoolSizeTask = null ;
143143 if ( ! this . #requests. isEmpty ( ) ) {
144144 this . _managePoolSize ( ) ;
145145 }
@@ -153,12 +153,21 @@ class Pool extends EventEmitter {
153153 * @param {number } timeoutEnd - Timestamp when connection attempt should time out
154154 */
155155 _createPoolConnection ( onSuccess , onError , timeoutEnd ) {
156- const minTimeout = timeoutEnd - Date . now ( ) ;
156+ if ( this . #closed) {
157+ this . #connectionCreationTask = null ;
158+ return ;
159+ }
160+
157161 const connectionOpts = Object . assign ( { } , this . opts . connOptions , {
158- connectTimeout : Math . max ( 1 , Math . min ( minTimeout , this . opts . connOptions . connectTimeout || Number . MAX_SAFE_INTEGER ) )
162+ connectTimeout : Math . max (
163+ 1 ,
164+ Math . min ( timeoutEnd - Date . now ( ) , this . opts . connOptions . connectTimeout || Number . MAX_SAFE_INTEGER )
165+ )
159166 } ) ;
167+
160168 const conn = new Connection ( connectionOpts ) ;
161- this . _connectionCreationTask = null ;
169+ this . #connectionCreationTask = null ;
170+
162171 // Use direct callback approach instead of Promise
163172 conn
164173 . connect ( )
@@ -288,13 +297,13 @@ class Pool extends EventEmitter {
288297 if ( isFatalError ) {
289298 // Fatal error - call error callback with additional pool info
290299 err . message = err . message + this . _errorMsgAddon ( ) ;
291- this . _connectionCreationTask = null ;
300+ this . #connectionCreationTask = null ;
292301 onError ( err ) ;
293302 return ;
294303 }
295304
296305 // Retry connection after delay
297- this . _connectionCreationTask = setTimeout (
306+ this . #connectionCreationTask = setTimeout (
298307 ( ) => this . _createPoolConnection ( onSuccess , onError , timeoutEnd ) ,
299308 Math . min ( 500 , timeoutEnd - Date . now ( ) )
300309 ) ;
@@ -341,21 +350,35 @@ class Pool extends EventEmitter {
341350 // Determine the cause of the timeout
342351 const timeoutCause = this . activeConnections ( ) === 0 ? this . #errorCreatingConnection : null ;
343352 const waitTime = Math . abs ( currentTime - ( request . timeout - this . opts . acquireTimeout ) ) ;
353+ let error ;
354+ if ( timeoutCause ) {
355+ error = Errors . createError (
356+ `pool failed to retrieve a connection from pool${ this . _errorMsgAddon ( ) } ` ,
357+ Errors . client . ER_GET_CONNECTION_TIMEOUT ,
358+ null ,
359+ 'HY000' ,
360+ null ,
361+ false ,
362+ request . stack ,
363+ null ,
364+ timeoutCause
365+ ) ;
366+ } else {
367+ // Create an appropriate error message with pool state information
368+ error = Errors . createError (
369+ `pool timeout: failed to retrieve a connection from pool after ${ waitTime } ms${ this . _errorMsgAddon ( ) } ` ,
370+ Errors . client . ER_GET_CONNECTION_TIMEOUT ,
371+ null ,
372+ 'HY000' ,
373+ null ,
374+ false ,
375+ request . stack ,
376+ null ,
377+ null
378+ ) ;
379+ }
344380
345- // Create an appropriate error message with pool state information
346- const timeoutError = Errors . createError (
347- `pool timeout: failed to retrieve a connection from pool after ${ waitTime } ms${ this . _errorMsgAddon ( ) } ` ,
348- Errors . client . ER_GET_CONNECTION_TIMEOUT ,
349- null ,
350- 'HY000' ,
351- null ,
352- false ,
353- request . stack ,
354- null ,
355- timeoutCause
356- ) ;
357-
358- request . reject ( timeoutError ) ;
381+ request . reject ( error ) ;
359382 }
360383
361384 /**
@@ -391,17 +414,18 @@ class Pool extends EventEmitter {
391414 }
392415
393416 this . _endLeak ( conn ) ;
394- this . #activeConnections[ conn . threadId ] = null ;
395417 conn . lastUse = Date . now ( ) ;
396418
397419 if ( this . #closed) {
420+ delete this . #activeConnections[ conn . threadId ] ;
398421 this . _cleanupConnection ( conn , 'pool_closed' ) ;
399422 return ;
400423 }
401424
402425 // Only basic validation here - full validation happens when acquiring
403426 if ( conn . isValid ( ) ) {
404427 this . emit ( 'release' , conn ) ;
428+ delete this . #activeConnections[ conn . threadId ] ;
405429 this . #idleConnections. push ( conn ) ;
406430 process . nextTick ( this . emit . bind ( this , '_idle' ) ) ;
407431 } else {
@@ -661,11 +685,7 @@ class Pool extends EventEmitter {
661685 * @return {number }
662686 */
663687 activeConnections ( ) {
664- let counter = 0 ;
665- for ( const connection of Object . values ( this . #activeConnections) ) {
666- if ( connection ) counter ++ ;
667- }
668- return counter ;
688+ return Object . keys ( this . #activeConnections) . length ;
669689 }
670690
671691 /**
@@ -784,9 +804,13 @@ class Pool extends EventEmitter {
784804
785805 this . #closed = true ;
786806 clearInterval ( this . #unusedConnectionRemoverId) ;
787- clearInterval ( this . _managePoolSizeTask ) ;
788- clearTimeout ( this . _connectionCreationTask ) ;
807+ clearInterval ( this . #managePoolSizeTask ) ;
808+ clearTimeout ( this . #connectionCreationTask ) ;
789809 clearTimeout ( this . #requestTimeoutId) ;
810+ this . #unusedConnectionRemoverId = null ;
811+ this . #managePoolSizeTask = null ;
812+ this . #connectionCreationTask = null ;
813+ this . #requestTimeoutId = null ;
790814
791815 const cmdParam = { } ;
792816 if ( this . opts . trace ) Error . captureStackTrace ( cmdParam ) ;
@@ -797,9 +821,6 @@ class Pool extends EventEmitter {
797821 idleConnectionsEndings . push ( new Promise ( conn . forceEnd . bind ( conn , cmdParam ) ) ) ;
798822 }
799823
800- clearTimeout ( this . #requestTimeoutId) ;
801- this . #requestTimeoutId = null ;
802-
803824 //reject all waiting tasks
804825 if ( ! this . #requests. isEmpty ( ) ) {
805826 const err = Errors . createError (
@@ -816,6 +837,7 @@ class Pool extends EventEmitter {
816837 task . reject ( err ) ;
817838 }
818839 }
840+ this . removeAllListeners ( ) ;
819841 const pool = this ;
820842 return Promise . all ( idleConnectionsEndings ) . then ( async ( ) => {
821843 if ( pool . activeConnections ( ) > 0 ) {
0 commit comments