@@ -84,6 +84,7 @@ class Pool extends EventEmitter {
84
84
this . options . max = this . options . max || this . options . poolSize || 10
85
85
this . options . maxUses = this . options . maxUses || Infinity
86
86
this . options . allowExitOnIdle = this . options . allowExitOnIdle || false
87
+ this . options . maxLifetimeSeconds = this . options . maxLifetimeSeconds || 0
87
88
this . log = this . options . log || function ( ) { }
88
89
this . Client = this . options . Client || Client || require ( 'pg' ) . Client
89
90
this . Promise = this . options . Promise || global . Promise
@@ -94,6 +95,7 @@ class Pool extends EventEmitter {
94
95
95
96
this . _clients = [ ]
96
97
this . _idle = [ ]
98
+ this . _expired = [ ]
97
99
this . _pendingQueue = [ ]
98
100
this . _endCallback = undefined
99
101
this . ending = false
@@ -123,6 +125,24 @@ class Pool extends EventEmitter {
123
125
}
124
126
return
125
127
}
128
+
129
+ // if there are idle clients; see if any lifetimes have expired
130
+ if ( this . _idle . length && this . _expired . length ) {
131
+ let newlyExpired = [ ]
132
+ this . _idle . forEach ( ( idleItem ) => {
133
+ const client = idleItem . client
134
+ const expiredIndex = this . _expired . findIndex ( c => c === client )
135
+ if ( - 1 !== expiredIndex ) {
136
+ newlyExpired . push ( expiredIndex )
137
+ }
138
+ } )
139
+ newlyExpired . forEach ( ( expiredIndex ) => {
140
+ this . log ( 'remove expired client' )
141
+ const expiredClient = this . _expired . splice ( expiredIndex , 1 ) [ 0 ]
142
+ this . _remove ( expiredClient )
143
+ } )
144
+ }
145
+
126
146
// if we don't have any waiting, do nothing
127
147
if ( ! this . _pendingQueue . length ) {
128
148
this . log ( 'no queued requests' )
@@ -248,6 +268,17 @@ class Pool extends EventEmitter {
248
268
} else {
249
269
this . log ( 'new client connected' )
250
270
271
+ if ( 0 !== this . options . maxLifetimeSeconds ) {
272
+ setTimeout ( ( ) => {
273
+ const expiredClient = this . _clients . findIndex ( c => c === client )
274
+ if ( - 1 !== expiredClient ) {
275
+ this . log ( 'ending client due to expired lifetime' )
276
+ this . _expired . push ( client )
277
+ this . _pulseQueue ( )
278
+ }
279
+ } , this . options . maxLifetimeSeconds * 1000 )
280
+ }
281
+
251
282
return this . _acquireClient ( client , pendingItem , idleListener , true )
252
283
}
253
284
} )
@@ -318,6 +349,15 @@ class Pool extends EventEmitter {
318
349
return
319
350
}
320
351
352
+ const expiredClient = this . _expired . findIndex ( c => c === client )
353
+ if ( - 1 !== expiredClient ) {
354
+ this . log ( 'remove expired client' )
355
+ this . _expired . splice ( expiredClient , 1 )
356
+ this . _remove ( client )
357
+ this . _pulseQueue ( )
358
+ return
359
+ }
360
+
321
361
// idle timeout
322
362
let tid
323
363
if ( this . options . idleTimeoutMillis ) {
@@ -414,6 +454,10 @@ class Pool extends EventEmitter {
414
454
return this . _idle . length
415
455
}
416
456
457
+ get expiredCount ( ) {
458
+ return this . _expired . length
459
+ }
460
+
417
461
get totalCount ( ) {
418
462
return this . _clients . length
419
463
}
0 commit comments