@@ -56,6 +56,7 @@ class Pool {
56
56
this . _maxSize = config . maxSize
57
57
this . _acquisitionTimeout = config . acquisitionTimeout
58
58
this . _pools = { }
59
+ this . _pendingCreates = { }
59
60
this . _acquireRequests = { }
60
61
this . _activeResourceCounts = { }
61
62
this . _release = this . _release . bind ( this )
@@ -73,18 +74,11 @@ class Pool {
73
74
const key = address . asKey ( )
74
75
75
76
if ( resource ) {
76
- if (
77
- this . _maxSize &&
78
- this . activeResourceCount ( address ) >= this . _maxSize
79
- ) {
80
- this . _destroy ( resource )
81
- } else {
82
- resourceAcquired ( key , this . _activeResourceCounts )
83
- if ( this . _log . isDebugEnabled ( ) ) {
84
- this . _log . debug ( `${ resource } acquired from the pool ${ key } ` )
85
- }
86
- return resource
77
+ resourceAcquired ( key , this . _activeResourceCounts )
78
+ if ( this . _log . isDebugEnabled ( ) ) {
79
+ this . _log . debug ( `${ resource } acquired from the pool ${ key } ` )
87
80
}
81
+ return resource
88
82
}
89
83
90
84
// We're out of resources and will try to acquire later on when an existing resource is released.
@@ -185,6 +179,7 @@ class Pool {
185
179
if ( ! pool ) {
186
180
pool = [ ]
187
181
this . _pools [ key ] = pool
182
+ this . _pendingCreates [ key ] = 0
188
183
}
189
184
while ( pool . length ) {
190
185
const resource = pool . pop ( )
@@ -201,12 +196,29 @@ class Pool {
201
196
}
202
197
}
203
198
204
- if ( this . _maxSize && this . activeResourceCount ( address ) >= this . _maxSize ) {
205
- return null
199
+ // Ensure requested max pool size
200
+ if ( this . _maxSize > 0 ) {
201
+ // Include pending creates when checking pool size since these probably will add
202
+ // to the number when fulfilled.
203
+ const numConnections =
204
+ this . activeResourceCount ( address ) + this . _pendingCreates [ key ]
205
+ if ( numConnections >= this . _maxSize ) {
206
+ // Will put this request in queue instead since the pool is full
207
+ return null
208
+ }
206
209
}
207
210
208
211
// there exist no idle valid resources, create a new one for acquisition
209
- return await this . _create ( address , this . _release )
212
+ // Keep track of how many pending creates there are to avoid making too many connections.
213
+ this . _pendingCreates [ key ] = this . _pendingCreates [ key ] + 1
214
+ let resource
215
+ try {
216
+ // Invoke callback that creates actual connection
217
+ resource = await this . _create ( address , this . _release )
218
+ } finally {
219
+ this . _pendingCreates [ key ] = this . _pendingCreates [ key ] - 1
220
+ }
221
+ return resource
210
222
}
211
223
212
224
async _release ( address , resource ) {
0 commit comments