Skip to content

Commit

Permalink
ignore calls to release() on a connection that has been closed or is …
Browse files Browse the repository at this point in the history
…not part of the connection pool
  • Loading branch information
ben-page committed Dec 13, 2014
1 parent bd43561 commit 16552dc
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 34 deletions.
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ A connection pool for [tedious](http://github.com/pekim/tedious).
## Installation

npm install tedious-connection-pool

##Description
The only difference from the regular tedious API is how the connection is obtained and released. Rather than creating a connection and then closing it when finished, acquire a connection from the pool and release it when finished. Releasing resets the connection and makes in available for another use.

Once the Tedious Connection object has been acquired, the tedious API can be used with the connection as normal.

## Example
The only difference from the regular tedious API is how the connection is obtained and released. Once a Connection object has been acquired, the tedious API can be used with the connection as normal.

```javascript
var ConnectionPool = require('tedious-connection-pool');
Expand All @@ -24,20 +28,23 @@ var connectionConfig = {
server: 'localhost'
};

//create the pool
var pool = new ConnectionPool(poolConfig, connectionConfig);

//acquire a connection
pool.acquire(function (err, connection) {
if (err)
console.error(err);

//use the connection as normal
var request = new Request('select 42', function(err, rowCount) {
if (err)
console.error(err);

console.log('rowCount: ' + rowCount);

connection.release(); // release the connection back to the pool.
pool.drain(); //drain the pool when finished using it
//release the connection back to the pool when finished
connection.release();
});

request.on('row', function(columns) {
Expand All @@ -52,7 +59,11 @@ pool.on('error', function(err) {
});
```

When the connection is released it is returned to the pool and is available to be reused.
When you are finished with the pool, you can drain it (close all connections).
```javascript
pool.drain(); //drain the pool when finished using it
```


##Class: ConnectionPool

Expand Down Expand Up @@ -89,6 +100,9 @@ The following method is added to the Tedious [Connection](http://pekim.github.co
### Connection.release()
Release the connect back to the pool to be used again

## Version 0.3.3 Changes
* Ignore calls to connection.release() on a connection that has been closed or not part of the connection pool.

## Version 0.3.2 Changes
* Calls connection.reset() when the connection is released to the pool. This is very unlikely to cause anyone trouble.
* Added a callback argument to connectionPool.drain()
Expand All @@ -106,4 +120,4 @@ Release the connect back to the pool to be used again
## Version 0.2.x Breaking Changes
* To acquire a connection, call on `acquire()` on a `ConnectionPool` rather than `requestConnection()`.
* After acquiring a `PooledConnection`, do not wait for the `'connected'` event. The connection is received connected.
* Call `release()` on a `PooledConnection` to release the it back to the pool. `close()` permanently closes the connection (as `close()` behaves in in tedious).
* Call `release()` on a `PooledConnection` to release the it back to the pool. `close()` permanently closes the connection (as `close()` behaves in in tedious).
55 changes: 29 additions & 26 deletions lib/connection-pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,24 @@ function ConnectionPool(poolConfig, connectionConfig) {

util.inherits(ConnectionPool, EventEmitter);

var cid = 1;

function createConnection(pooled) {
if (this.drained) //pool has been drained
return;

var self = this;

this.log('creating connection');
this.log('creating connection: ' + cid);
var connection = new Connection(this.connectionConfig);
connection.pool = this;
if (pooled) {
pooled.id = cid++;
pooled.con = connection;
pooled.status = PENDING;
} else {
pooled = {
id: cid++,
con: connection,
status: PENDING
};
Expand All @@ -86,7 +90,7 @@ function createConnection(pooled) {
};

connection.on('connect', function (err) {
self.log('connection connected');
self.log('connection connected: ' + pooled.id);
if (self.drained) { //pool has been drained
self.log('connection closing because pool is drained');
connection.close();
Expand All @@ -108,7 +112,7 @@ function createConnection(pooled) {
connection.on('error', handleError);

connection.on('end', function () {
self.log('connection ended');
self.log('connection ended: ' + pooled.id);
if (self.drained) //pool has been drained
return;

Expand Down Expand Up @@ -142,7 +146,7 @@ function fill() {
amount);

if (amount > 0)
this.log('filling ' + amount);
this.log('filling pool with ' + amount);

for (i = 0; i < amount; i++)
createConnection.call(this);
Expand Down Expand Up @@ -179,7 +183,7 @@ ConnectionPool.prototype.acquire = function (callback) {

if (waiter2.timeout === waiter.timeout) {
self.waiting.splice(i, 1);
waiter.callback(new Error('Acquire Timeout'));
waiter.callback(new Error('Acquire Timeout Exceeded'));
return;
}
}
Expand Down Expand Up @@ -207,7 +211,7 @@ function setFree(pooled) {

pooled.status = FREE;
pooled.timeout = setTimeout(function() {
self.log('closing idle connection');
self.log('closing idle connection: ' + pooled.id);
pooled.con.close();
}, this.idleTimeout);
}
Expand All @@ -221,34 +225,33 @@ ConnectionPool.prototype.release = function(connection) {
var self = this;
var i, pooled;

connection.reset(function (err) {
if (err) { //there is an error, don't reuse the connection, just close it
for (i = self.connections.length - 1; i >= 0; i--) {
pooled = self.connections[i];
if (pooled.con === connection) {
for (i = self.connections.length - 1; i >= 0; i--) {
pooled = self.connections[i];

if (pooled.con === connection) {
//reset connection & release it
connection.reset(function (err) {
if (err) { //there is an error, don't reuse the connection, just close it
pooled.con.close();
return;
}
}
}
self.log('connection reset');
self.log('connection reset: ' + pooled.id);

var waiter = self.waiting.shift();
var waiter = self.waiting.shift();

if (waiter !== undefined) {
if (waiter.timeout)
clearTimeout(waiter.timeout);
waiter.callback(null, connection);
} else {
for (i = self.connections.length - 1; i >= 0; i--) {
pooled = self.connections[i];
if (pooled.con === connection) {
if (waiter !== undefined) {
setUsed.call(self, pooled, waiter);
//if (waiter.timeout)
// clearTimeout(waiter.timeout);
//waiter.callback(null, connection);
} else {
setFree.call(self, pooled);
break;
}
}
});

return;
}
});
}
};

ConnectionPool.prototype.drain = function (callback) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tedious-connection-pool",
"version": "0.3.2",
"version": "0.3.3",
"description": "Connection Pool for tedious.",
"main": "lib/connection-pool.js",
"scripts": {
Expand Down Expand Up @@ -42,7 +42,7 @@
}
],
"devDependencies": {
"tedious": ">=1.7.0",
"tedious": ">=1.8.0",
"mocha": ">=1.6.0"
},
"licenses": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion test/load-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var p = 0;

var createRequest = function (err, connection) {
if (err)
console.err(err);
console.error(err);

if (c >= total)
return;
Expand Down

0 comments on commit 16552dc

Please sign in to comment.