Socket
Socket
Sign inDemoInstall

tarn

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tarn - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

132

index.js
var Promise = require('bluebird');
var RECURSION_LIMIT = 100;

@@ -26,16 +27,16 @@ function Tarn(opt) {

if (!checkOptionalTime(opt.acquireTimeoutMs)) {
throw new Error('Tarn: invalid opt.acquireTimeoutMs ' + JSON.stringify(opt.acquireTimeoutMs));
if (!checkOptionalTime(opt.acquireTimeoutMillis)) {
throw new Error('Tarn: invalid opt.acquireTimeoutMillis ' + JSON.stringify(opt.acquireTimeoutMillis));
}
if (!checkOptionalTime(opt.createTimeoutMs)) {
throw new Error('Tarn: invalid opt.createTimeoutMs ' + JSON.stringify(opt.createTimeoutMs));
if (!checkOptionalTime(opt.createTimeoutMillis)) {
throw new Error('Tarn: invalid opt.createTimeoutMillis ' + JSON.stringify(opt.createTimeoutMillis));
}
if (!checkOptionalTime(opt.idleTimeoutMs)) {
throw new Error('Tarn: invalid opt.idleTimeoutMs ' + JSON.stringify(opt.idleTimeoutMs));
if (!checkOptionalTime(opt.idleTimeoutMillis)) {
throw new Error('Tarn: invalid opt.idleTimeoutMillis ' + JSON.stringify(opt.idleTimeoutMillis));
}
if (!checkOptionalTime(opt.reapIntervalMs)) {
throw new Error('Tarn: invalid opt.reapIntervalMs ' + JSON.stringify(opt.reapIntervalMs));
if (!checkOptionalTime(opt.reapIntervalMillis)) {
throw new Error('Tarn: invalid opt.reapIntervalMillis ' + JSON.stringify(opt.reapIntervalMillis));
}

@@ -45,8 +46,9 @@

this.destroyer = opt.destroy;
this.validate = typeof opt.validate === 'function' ? opt.validate : function () { return true; };
this.log = opt.log || function () {};
this.acquireTimeoutMs = opt.acquireTimeoutMs || 30000;
this.createTimeoutMs = opt.createTimeoutMs || 30000;
this.idleTimeoutMs = opt.idleTimeoutMs || 30000;
this.reapIntervalMs = opt.reapIntervalMs || 1000;
this.acquireTimeoutMillis = opt.acquireTimeoutMillis || 30000;
this.createTimeoutMillis = opt.createTimeoutMillis || 30000;
this.idleTimeoutMillis = opt.idleTimeoutMillis || 30000;
this.reapIntervalMillis = opt.reapIntervalMillis || 1000;

@@ -65,3 +67,3 @@ this.min = opt.min;

self.check();
}, this.reapIntervalMs);
}, this.reapIntervalMillis);
}

@@ -88,3 +90,3 @@

var pendingAcquire = new PendingOperation(this.acquireTimeoutMs);
var pendingAcquire = new PendingOperation(this.acquireTimeoutMillis);
this.pendingAcquires.push(pendingAcquire);

@@ -97,3 +99,3 @@

this._tryAcquireNext();
this._tryAcquireNext(0);
return pendingAcquire;

@@ -109,3 +111,3 @@ };

this.free.push(new FreeResource(used.resource));
this._tryAcquireNext();
this._tryAcquireNext(0);
return true;

@@ -128,3 +130,3 @@ }

if (duration(timestamp, free.timestamp) > this.idleTimeoutMs && numDestroyed < maxDestroy) {
if (duration(timestamp, free.timestamp) > this.idleTimeoutMillis && numDestroyed < maxDestroy) {
numDestroyed++;

@@ -144,4 +146,6 @@ this._destroy(free.resource);

Tarn.prototype._tryAcquireNext = function () {
if (this.used.length >= this.max || this.pendingAcquires.length === 0) {
Tarn.prototype._tryAcquireNext = function (recursion) {
recursion = (recursion || 0) + 1;
if (this.used.length >= this.max || this.pendingAcquires.length === 0 || recursion > RECURSION_LIMIT) {
// Nothing to do.

@@ -152,3 +156,3 @@ return;

if (this.free.length > 0) {
this._acquireNext();
this._acquireNext(recursion);
} else if (this.used.length + this.pendingCreates.length < this.max && this.pendingCreates.length < this.pendingAcquires.length) {

@@ -158,5 +162,5 @@ var self = this;

this._create().promise.then(function () {
self._tryAcquireNext();
self._tryAcquireNext(recursion);
}).catch(function (err) {
self.log('Tarn: resource creator threw an exception', err.stack);
self.log('Tarn: resource creator threw an exception ' + err.stack, 'warn');
});

@@ -166,13 +170,29 @@ }

Tarn.prototype._acquireNext = function () {
Tarn.prototype._acquireNext = function (recursion) {
while (this.free.length > 0 && this.pendingAcquires.length > 0) {
var pendingAcquire = this.pendingAcquires.shift();
var pendingAcquire = this.pendingAcquires[0];
var free = this.free[0];
if (!pendingAcquire.isRejected()) {
var free = this.free.shift();
if (pendingAcquire.isRejected()) {
this.pendingAcquires.shift();
continue;
}
this.used.push(new UsedResource(free.resource));
pendingAcquire._resolve(free.resource);
if (!this.validate(free.resource)) {
this.free.shift();
this._destroy(free.resource);
continue;
}
this.pendingAcquires.shift();
this.free.shift();
this.used.push(new UsedResource(free.resource));
pendingAcquire._resolve(free.resource);
}
// If we destroyed invalid resources, we may need to create new ones.
if (this.pendingAcquires.length > this.pendingCreates.length) {
this._tryAcquireNext(recursion);
}
};

@@ -183,27 +203,21 @@

var pendingCreate = new PendingOperation(this.createTimeoutMs);
var pendingCreate = new PendingOperation(this.createTimeoutMillis);
this.pendingCreates.push(pendingCreate);
// nextTick is needed to make sure the creation happens asynchronously.
try {
self.creator(function (err, resource) {
remove(self.pendingCreates, pendingCreate);
callbackOrPromise(self.creator, []).then(function (resource) {
remove(self.pendingCreates, pendingCreate);
if (err) {
pendingCreate._reject(err);
} else {
if (pendingCreate.isRejected()) {
// This happens if the pending operation times out or is aborted. In any case,
// we need to destroy the resource since no-one will ever use it.
this._destroy(resource);
} else {
self.free.push(new FreeResource(resource));
pendingCreate._resolve(resource);
}
}
});
} catch (err) {
if (pendingCreate.isRejected()) {
// This happens if the pending operation times out or is aborted. In any case,
// we need to destroy the resource since no-one will ever use it.
this._destroy(resource);
} else {
self.free.push(new FreeResource(resource));
pendingCreate._resolve(resource);
}
}).catch(function (err) {
remove(self.pendingCreates, pendingCreate);
pendingCreate._reject(err);
}
});

@@ -217,3 +231,3 @@ return pendingCreate;

} catch (err) {
this.log('Tarn: resource destroyer threw an exception', err.stack);
this.log('Tarn: resource destroyer threw an exception ' + err.stack, 'warn');
}

@@ -283,4 +297,24 @@ };

function callbackOrPromise(func, args) {
return new Promise(function (resolve, reject) {
args.push(function (err, resource) {
if (err) {
reject(err);
} else {
resolve(resource);
}
});
Promise.try(function () {
return func.apply(undefined, args);
}).then(function (res) {
if (res) {
resolve(res);
}
}).catch(reject);
});
}
module.exports = {
Tarn: Tarn
};
{
"name": "tarn",
"version": "0.1.0",
"version": "0.1.1",
"description": "Simple and robust resource pool for node.js",

@@ -8,3 +8,4 @@ "main": "index.js",

"scripts": {
"test": "mocha --slow 10 --timeout 5000 --reporter spec tests.js"
"test": "mocha --slow 10 --timeout 5000 --reporter spec tests.js",
"test-bail": "mocha --slow 10 --timeout 5000 --reporter spec --bail tests.js"
},

@@ -11,0 +12,0 @@ "author": {

[![Build Status](https://travis-ci.org/Vincit/tarn.js.svg?branch=master)](https://travis-ci.org/Vincit/tarn.js)
## Why yet another pool for node?
## Why yet another resource pool?
Tarn is focused in robustness and ability to recover from errors. Tarn has timeouts for all operations
Tarn is focused on robustness and ability to recover from errors. Tarn has timeouts for all operations
that can fail or timeout so that you should never end up with pool full of crap. Tarn has a comprehensive

@@ -24,3 +24,5 @@ test suite and we are committed to adding tests and fixing all bugs that are found.

// function that creates a resource
// function that creates a resource. You can either pass the resource
// to the callback or return a promise that resolves the resource
// (but not both).
create: (cb) => {

@@ -30,3 +32,11 @@ cb(null, new SomeResource());

// function that destroys a resource
// validates a connection before it is used. Return true or false
// from it. If false is returned, the resource is destroyed and a
// another one is acquired.
validate: (resource) {
return true;
},
// function that destroys a resource. This is always synchronous
// as nothing waits for the return value.
destroy: (someResource) => {

@@ -44,13 +54,13 @@ someResource.cleanup();

// if a resource cannot be acquired
acquireTimeoutMs: 30000,
acquireTimeoutMillis: 30000,
// create operations are cancelled after this many milliseconds
// if a resource cannot be acquired
createTimeoutMs: 30000,
createTimeoutMillis: 30000,
// free resouces are destroyed after this many milliseconds
idleTimeoutMs: 30000,
idleTimeoutMillis: 30000,
// how often to check for idle resources to destroy
reapIntervalMs: 1000
reapIntervalMillis: 1000
});

@@ -57,0 +67,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