Socket
Socket
Sign inDemoInstall

generic-pool

Package Overview
Dependencies
Maintainers
2
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

generic-pool - npm Package Compare versions

Comparing version 3.0.0-alpha.9 to 3.0.0-beta.1

11

CHANGELOG.md
# Change Log
## [3.0.0] - October xx 2016
## [3.0.0] - October 30 2016
- This is pretty big and the migration guide in the README has more detailed set of changes!

@@ -13,2 +13,5 @@ - switch support to nodejs v4 and above

## [2.4.3] - October 15 2016
- Use domain.bind to preserve domain context (@LewisJEllis)
## [2.4.2] - March 26 2016

@@ -120,4 +123,8 @@ - Travis now runs and fails lint checks (@kevinburke)

[unreleased]: https://github.com/coopernurse/node-pool/compare/v2.4.2...HEAD
<<<<<<< HEAD
=======
[unreleased]: https://github.com/coopernurse/node-pool/compare/v3.0.0...HEAD
[3.0.0]: https://github.com/coopernurse/node-pool/compare/v2.4.1...v3.0.0
[2.4.3]: https://github.com/coopernurse/node-pool/compare/v2.4.2...v2.4.3
[2.4.2]: https://github.com/coopernurse/node-pool/compare/v2.4.1...v2.4.2

@@ -124,0 +131,0 @@ [2.4.1]: https://github.com/coopernurse/node-pool/compare/v2.4.0...v2.4.1

82

lib/Pool.js

@@ -195,5 +195,3 @@ 'use strict'

* Attempt to resolve an outstanding resource request using an available resource from
* the pool.
* Shuffles things through
* TODO: rename this!
* the pool, or creating new ones
*

@@ -203,4 +201,2 @@ * @private

_dispense () {
// console.log('_dispense called')
/**

@@ -213,4 +209,4 @@ * Local variables for ease of reading/writing

// If there aren't any waiting requests then there is nothing to do
// so lets short-circuit
if (numWaitingClients < 1) {
// console.log('dispense bailing - no waiting requests')
return

@@ -222,8 +218,2 @@ }

if (this._config.testOnBorrow === true) {
// console.log('dispense - entering test-on-borrow branch')
// Could all the outstanding clients be fulfilled by resources under going test-on-borrow
if (numWaitingClients <= this._testOnBorrowResources.size) {
// console.log('dispense bailing - all waiting requests could be fulfilled by resources in test-on-borrow')
return
}
// how many available resources do we need to shift into test

@@ -235,3 +225,2 @@ const desiredNumberOfResourcesToMoveIntoTest = numWaitingClients - this._testOnBorrowResources.size

}
// console.log('dispense - leaving test-on-borrow branch')
}

@@ -247,15 +236,6 @@

if (resourceShortfall > 0) {
// console.log('dispense - entering resource shortfall branch')
const spareResourceCapacity = this._config.max - (this._allObjects.size + this._factoryCreateOperations.size)
if (spareResourceCapacity < 1) {
// console.log('not enough allocable resources to satisfy all waiting clients and at max capacity')
}
const actualNumberOfResourcesToCreate = Math.min(spareResourceCapacity, resourceShortfall)
for (let i = 0; actualNumberOfResourcesToCreate > i; i++) {
this._createResource()
}
// console.log('dispense - leaving resource shortfall branch')
const spareResourceCapacity = this._config.max - (this._allObjects.size + this._factoryCreateOperations.size)
const actualNumberOfResourcesToCreate = Math.min(spareResourceCapacity, resourceShortfall)
for (let i = 0; actualNumberOfResourcesToCreate > i; i++) {
this._createResource()
}

@@ -265,3 +245,2 @@

if (this._config.testOnBorrow === false) {
// console.log('dispense - entering non test-on-borrow branch')
const actualNumberOfResourcesToDispatch = Math.min(this._availableObjects.length, numWaitingClients)

@@ -271,5 +250,3 @@ for (let i = 0; actualNumberOfResourcesToDispatch > i; i++) {

}
// console.log('dispense - leaving non test-on-borrow branch')
}
// console.log('dispense finished')
}

@@ -318,3 +295,2 @@

})
.then()
}

@@ -384,3 +360,3 @@

this._scheduledEviction = setTimeout(() => {
this.evict()
this._evict()
this._scheduleEvictorRun()

@@ -551,2 +527,3 @@ }, this._config.evictionRunIntervalMillis)

}
// TODO: we should handle factory.destroy rejecting...
return this._Promise.all(this._factoryDestroyOperations)

@@ -556,45 +533,2 @@ }

/**
* Decorates a function to use an acquired resource from the object pool when called.
*
* @param {Function} decorated
* The decorated function, accepting a resource as the first argument and
* (optionally) a callback as the final argument.
*
* @param {Number} priority
* Optional. Integer between 0 and (priorityRange - 1). Specifies the priority
* of the caller if there are no available resources. Lower numbers mean higher
* priority.
*/
pooled (decorated, priority) {
const self = this
return function () {
const callerArgs = arguments
const callerCallback = callerArgs[callerArgs.length - 1]
const callerHasCallback = typeof callerCallback === 'function'
self.acquire(priority)
.then(_onAcquire)
.catch(function (err) {
if (callerHasCallback) {
callerCallback(err)
}
})
function _onAcquire (resource) {
function _wrappedCallback () {
self.release(resource)
if (callerHasCallback) {
callerCallback.apply(null, arguments)
}
}
const args = [resource].concat(Array.prototype.slice.call(callerArgs, 0, callerHasCallback ? -1 : undefined))
args.push(_wrappedCallback)
decorated.apply(null, args)
}
}
}
/**
* The combined count of the currently created objects and those in the

@@ -601,0 +535,0 @@ * process of being created

@@ -10,4 +10,2 @@ 'use strict'

this.fifo = true
this.refreshIdle = true
this.reapIntervalMillis = 1000
this.priorityRange = 1

@@ -14,0 +12,0 @@

@@ -19,4 +19,2 @@ 'use strict'

* maximum number of queued requests allowed after which acquire calls will be rejected
* @param {Number} config.reapIntervalMillis
* Cleanup is scheduled in every `config.reapIntervalMillis` milliseconds.
* @param {Number} config.acquireTimeoutMillis

@@ -27,4 +25,2 @@ * Delay in milliseconds after which the an `acquire` call will fail. optional.

* The range from 1 to be treated as a valid priority
* @param {RefreshIdle} config.refreshIdle
* Should idle resources be destroyed and recreated every idleTimeoutMillis? Default: true.
* @param {Bool} [config.fifo=true]

@@ -55,4 +51,2 @@ * Sets whether the pool has LIFO (last in, first out) behaviour with respect to idle objects.

this.fifo = (typeof opts.fifo === 'boolean') ? opts.fifo : poolDefaults.fifo
this.refreshIdle = ('refreshIdle' in opts) ? opts.refreshIdle : poolDefaults.refreshIdle
this.reapInterval = opts.reapIntervalMillis || poolDefaults.reapIntervalMillis
this.priorityRange = opts.priorityRange || poolDefaults.priorityRange

@@ -59,0 +53,0 @@

{
"name": "generic-pool",
"description": "Generic resource pooling for Node.JS",
"version": "3.0.0-alpha.9",
"version": "3.0.0-beta.1",
"author": "James Cooper <james@bitmechanic.com>",

@@ -50,2 +50,6 @@ "contributors": [

"email": "james.butler@sandfox.co.uk"
},
{
"name": "Lewis J Ellis",
"email": "me@lewisjellis.com"
}

@@ -52,0 +56,0 @@ ],

@@ -137,4 +137,3 @@ [![build status](https://secure.travis-ci.org/coopernurse/node-pool.png)](http://travis-ci.org/coopernurse/node-pool)

- `maxWaitingClients`: maximum number of queued requests allowed, additional `acquire` calls will be callback with an `err` in a future cycle of the event loop.
- `testOnBorrow`: `boolean`: should the pool validate resources before giving them to clients. Requires that either `factory.validate` or `factory.validateAsync` to be specified.
- `refreshIdle`: `boolean` that specifies whether idle resources at or below the min threshold should be destroyed/re-created. (default=true)
- `testOnBorrow`: `boolean`: should the pool validate resources before giving them to clients. Requires that either `factory.validate` or `factory.validateAsync` to be specified
- `idleTimeoutMillis`: max milliseconds a resource can stay unused in the pool without being borrowed before it should be destroyed (default 30000)

@@ -212,4 +211,6 @@ - `reapIntervalMillis`: interval to check for idle resources (default 1000). (remove me!)

The pool has an evictor (off by default) which will inspect idle items in the pool and `destroy` them if they are too old
The pool has an evictor (off by default) which will inspect idle items in the pool and `destroy` them if they are too old.
By default the evictor does not run, to enable it you must set the `evictionRunIntervalMillis` option to a non-zero value. Once enable the evictor will check at most `numTestsPerEvictionRun` each time, this is to stop it blocking your application if you have lots of resources in the pool.
## Draining

@@ -301,33 +302,4 @@

To transparently handle object acquisition for a function,
one can use `pooled()`:
This has now been extracted out it's own module [generic-pool-decorator](https://github.com/sandfox/generic-pool-decorator)
```js
var privateFn, publicFn;
publicFn = pool.pooled(privateFn = function(client, arg, cb) {
// Do something with the client and arg. Client is auto-released when cb is called
cb(null, arg);
});
```
Keeping both private and public versions of each function allows for pooled
functions to call other pooled functions with the same member. This is a handy
pattern for database transactions:
```js
var privateTop, privateBottom, publicTop, publicBottom;
publicBottom = pool.pooled(privateBottom = function(client, arg, cb) {
//Use client, assumed auto-release
});
publicTop = pool.pooled(privateTop = function(client, cb) {
// e.g., open a database transaction
privateBottom(client, "arg", function(err, retVal) {
if(err) { return cb(err); }
// e.g., close a transaction
cb();
});
});
```
## Pool info

@@ -334,0 +306,0 @@

@@ -12,4 +12,3 @@ 'use strict'

// const config = {
// max: 1,
// refreshIdle: false,
// max: 1
// }

@@ -42,4 +41,3 @@

// min: 1,
// max: 2,
// refreshIdle: false
// max: 2
// }

@@ -61,8 +59,4 @@

const config = {
refreshIdle: false
}
const pool = new Pool(resourceFactory)
const pool = new Pool(resourceFactory, config)
t.equal(1, pool.max)

@@ -78,3 +72,2 @@ t.equal(0, pool.min)

const config = {
refreshIdle: false,
min: 'asf',

@@ -95,3 +88,2 @@ max: []

const config = {
refreshIdle: false,
min: 5,

@@ -118,3 +110,2 @@ max: 3

max: 1,
refreshIdle: false,
priorityRange: 2

@@ -167,4 +158,3 @@ }

// const config
// max: 2,
// refreshIdle: false
// max: 2
// }

@@ -199,2 +189,25 @@

tap.test('evictor removes instances on idletimeout', function (t) {
const resourceFactory = new ResourceFactory()
const config = {
min: 2,
max: 2,
idleTimeoutMillis: 50,
evictionRunIntervalMillis: 10
}
const pool = new Pool(resourceFactory, config)
setTimeout(function () {
pool.acquire()
.then((res) => {
t.ok(res.id > 1)
return pool.release(res)
})
.then(() => {
utils.stopPool(pool)
t.end()
})
}, 120)
})
tap.test('tests drain', function (t) {

@@ -341,171 +354,2 @@ const count = 5

tap.test('pooled decorator should acquire and release', function (t) {
// FIXME: assertion count should probably be replaced with t.plan?
let assertionCount = 0
const resourceFactory = new ResourceFactory()
const config = {
max: 1,
refreshIdle: false
}
const pool = new Pool(resourceFactory, config)
const pooledFn = pool.pooled(function (client, cb) {
t.equal(typeof client.id, 'number')
t.equal(pool.size, 1)
assertionCount += 2
cb()
})
t.equal(pool.size, 0)
assertionCount += 1
pooledFn(function (err) {
// FIXME: what is even happening in this block?
if (err) { throw err }
t.ok(true)
assertionCount += 1
})
utils.stopPool(pool)
.then(function () {
t.equal(assertionCount, 4)
t.end()
})
})
tap.test('pooled decorator should pass arguments and return values', function (t) {
// FIXME: assertion count should probably be replaced with t.plan?
let assertionCount = 0
const resourceFactory = new ResourceFactory()
const config = {
max: 1
}
const pool = new Pool(resourceFactory, config)
const pooledFn = pool.pooled(function (client, arg1, arg2, cb) {
t.equal(arg1, 'First argument')
t.equal(arg2, 'Second argument')
assertionCount += 2
cb(null, 'First return', 'Second return')
})
pooledFn('First argument', 'Second argument', function (err, retVal1, retVal2) {
if (err) { throw err }
t.equal(retVal1, 'First return')
t.equal(retVal2, 'Second return')
assertionCount += 2
})
utils.stopPool(pool)
.then(function () {
t.equal(assertionCount, 4)
t.end()
})
})
// FIXME: I'm not really sure what this testing...
tap.test('pooled decorator should allow undefined callback', function (t) {
let assertionCount = 0
const resourceFactory = new ResourceFactory()
const config = {
max: 1,
refreshIdle: false
}
const pool = new Pool(resourceFactory, config)
const pooledFn = pool.pooled(function (client, arg, cb) {
t.equal(arg, 'Arg!')
assertionCount += 1
cb()
})
pooledFn('Arg!')
t.equal(pool.size, 1)
utils.stopPool(pool)
.then(function () {
t.equal(assertionCount, 1)
t.end()
})
})
tap.test('pooled decorator should not forward pool factory errors', function (t) {
let assertionCount = 0
let attempts = 0
const resourceFactory = {
create: function () {
attempts++
if (attempts <= 1) {
return Promise.reject(new Error('Error occurred.'))
} else {
return Promise.resolve({ id: attempts })
}
},
destroy: function (client) { return Promise.resolve() }
}
const pool = new Pool(resourceFactory,
{
max: 1
})
const pooledFn = pool.pooled(function (resource, cb) {
cb()
})
pooledFn(function (err, obj) {
t.error(err, 'Pool error was forwarded!')
assertionCount++
})
utils.stopPool(pool)
.then(function () {
t.equal(assertionCount, 1)
t.end()
})
})
tap.test('pooled decorator should forward pool acquire timeout errors', function (t) {
let assertionCount = 0
let attempts = 0
const resourceFactory = {
create: function () {
attempts++
return new Promise(function (resolve) {
setTimeout(function () {
resolve({ id: attempts })
}, 20)
})
},
destroy: function (client) { return Promise.resolve() }
}
const pool = new Pool(resourceFactory,
{
acquireTimeoutMillis: 10,
max: 1
})
const pooledFn = pool.pooled(function (resource, cb) {
cb()
})
pooledFn(function (err, obj) {
t.match(err, /ResourceRequest timed out/)
assertionCount++
})
utils.stopPool(pool)
.then(function () {
t.equal(assertionCount, 1)
t.end()
})
})
tap.test('getPoolSize', function (t) {

@@ -515,4 +359,3 @@ let assertionCount = 0

const config = {
max: 2,
refreshIdle: false
max: 2
}

@@ -566,4 +409,3 @@

const config = {
max: 2,
refreshIdle: false
max: 2
}

@@ -708,4 +550,3 @@

const config = {
max: 1,
refreshIdle: false
max: 1
}

@@ -712,0 +553,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc