@@ -26,15 +26,18 @@ const {
26
26
27
27
class Pool {
28
28
/**
29
- * @param {function(address: ServerAddress, function(address: ServerAddress, resource: object): Promise<object>): Promise<object> } create
29
+ * @param {function(acquisitionContext: object, address: ServerAddress, function(address: ServerAddress, resource: object): Promise<object>): Promise<object> } create
30
30
* an allocation function that creates a promise with a new resource. It's given an address for which to
31
31
* allocate the connection and a function that will return the resource to the pool if invoked, which is
32
32
* meant to be called on .dispose or .close or whatever mechanism the resource uses to finalize.
33
+ * @param {function(acquisitionContext: object, resource: object): boolean } validateOnAcquire
34
+ * called at various times when an instance is acquired
35
+ * If this returns false, the resource will be evicted
36
+ * @param {function(resource: object): boolean } validateOnRelease
37
+ * called at various times when an instance is released
38
+ * If this returns false, the resource will be evicted
33
39
* @param {function(resource: object): Promise<void> } destroy
34
40
* called with the resource when it is evicted from this pool
35
- * @param {function(resource: object): boolean } validate
36
- * called at various times (like when an instance is acquired and when it is returned.
37
- * If this returns false, the resource will be evicted
38
41
* @param {function(resource: object, observer: { onError }): void } installIdleObserver
39
42
* called when the resource is released back to pool
40
43
* @param {function(resource: object): void } removeIdleObserver
@@ -43,17 +46,19 @@ class Pool {
43
46
* @param {Logger } log the driver logger.
44
47
*/
45
48
constructor ( {
46
- create = ( address , release ) => Promise . resolve ( ) ,
49
+ create = ( acquisitionContext , address , release ) => Promise . resolve ( ) ,
47
50
destroy = conn => Promise . resolve ( ) ,
48
- validate = conn => true ,
51
+ validateOnAcquire = ( acquisitionContext , conn ) => true ,
52
+ validateOnRelease = ( conn ) => true ,
49
53
installIdleObserver = ( conn , observer ) => { } ,
50
54
removeIdleObserver = conn => { } ,
51
55
config = PoolConfig . defaultConfig ( ) ,
52
56
log = Logger . noOp ( )
53
57
} = { } ) {
54
58
this . _create = create
55
59
this . _destroy = destroy
56
- this . _validate = validate
60
+ this . _validateOnAcquire = validateOnAcquire
61
+ this . _validateOnRelease = validateOnRelease
57
62
this . _installIdleObserver = installIdleObserver
58
63
this . _removeIdleObserver = removeIdleObserver
59
64
this . _maxSize = config . maxSize
@@ -69,10 +74,11 @@ class Pool {
69
74
70
75
/**
71
76
* Acquire and idle resource fom the pool or create a new one.
77
+ * @param {object } acquisitionContext the acquisition context used for create and validateOnAcquire connection
72
78
* @param {ServerAddress } address the address for which we're acquiring.
73
79
* @return {Promise<Object> } resource that is ready to use.
74
80
*/
75
- acquire ( address ) {
81
+ acquire ( acquisitionContext , address ) {
76
82
const key = address . asKey ( )
77
83
78
84
// We're out of resources and will try to acquire later on when an existing resource is released.
@@ -108,7 +114,7 @@ class Pool {
108
114
}
109
115
} , this . _acquisitionTimeout )
110
116
111
- request = new PendingRequest ( key , resolve , reject , timeoutId , this . _log )
117
+ request = new PendingRequest ( key , acquisitionContext , resolve , reject , timeoutId , this . _log )
112
118
allRequests [ key ] . push ( request )
113
119
this . _processPendingAcquireRequests ( address )
114
120
} )
@@ -193,7 +199,7 @@ class Pool {
193
199
return pool
194
200
}
195
201
196
- async _acquire ( address ) {
202
+ async _acquire ( acquisitionContext , address ) {
197
203
if ( this . _closed ) {
198
204
throw newError ( 'Pool is closed, it is no more able to serve requests.' )
199
205
}
@@ -207,7 +213,7 @@ class Pool {
207
213
this . _removeIdleObserver ( resource )
208
214
}
209
215
210
- if ( await this . _validate ( resource ) ) {
216
+ if ( await this . _validateOnAcquire ( acquisitionContext , resource ) ) {
211
217
// idle resource is valid and can be acquired
212
218
resourceAcquired ( key , this . _activeResourceCounts )
213
219
if ( this . _log . isDebugEnabled ( ) ) {
@@ -238,7 +244,7 @@ class Pool {
238
244
let resource
239
245
try {
240
246
// Invoke callback that creates actual connection
241
- resource = await this . _create ( address , ( address , resource ) => this . _release ( address , resource , pool ) )
247
+ resource = await this . _create ( acquisitionContext , address , ( address , resource ) => this . _release ( address , resource , pool ) )
242
248
243
249
pool . pushInUse ( resource )
244
250
resourceAcquired ( key , this . _activeResourceCounts )
@@ -256,7 +262,7 @@ class Pool {
256
262
257
263
if ( pool . isActive ( ) ) {
258
264
// there exist idle connections for the given key
259
- if ( ! await this . _validate ( resource ) ) {
265
+ if ( ! await this . _validateOnRelease ( resource ) ) {
260
266
if ( this . _log . isDebugEnabled ( ) ) {
261
267
this . _log . debug (
262
268
`${ resource } destroyed and can't be released to the pool ${ key } because it is not functional`
@@ -327,7 +333,7 @@ class Pool {
327
333
const pendingRequest = requests . shift ( ) // pop a pending acquire request
328
334
329
335
if ( pendingRequest ) {
330
- this . _acquire ( address )
336
+ this . _acquire ( pendingRequest . context , address )
331
337
. catch ( error => {
332
338
// failed to acquire/create a new connection to resolve the pending acquire request
333
339
// propagate the error by failing the pending request
@@ -391,15 +397,20 @@ function resourceReleased (key, activeResourceCounts) {
391
397
}
392
398
393
399
class PendingRequest {
394
- constructor ( key , resolve , reject , timeoutId , log ) {
400
+ constructor ( key , context , resolve , reject , timeoutId , log ) {
395
401
this . _key = key
402
+ this . _context = context
396
403
this . _resolve = resolve
397
404
this . _reject = reject
398
405
this . _timeoutId = timeoutId
399
406
this . _log = log
400
407
this . _completed = false
401
408
}
402
409
410
+ get context ( ) {
411
+ return this . _context
412
+ }
413
+
403
414
isCompleted ( ) {
404
415
return this . _completed
405
416
}
0 commit comments