Skip to content

Commit

Permalink
properly uses latest the version of generic pool
Browse files Browse the repository at this point in the history
validate connections
releasing connections that close for any reason
remove unnecessary events
  • Loading branch information
ben-page committed Oct 28, 2014
1 parent 7196130 commit 7b88ee9
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 130 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
npm-debug.log
node_modules/
*.sublime-*
.idea/
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,67 @@
# tedious-connection-pool
A simple connection pool for [tedious](http://github.com/pekim/tedious).

Status: Experimental

## Example
The only difference from the regular tedious API is how the connection is obtained.
Once a Connection object has been acquired, the tedious API can be used with the
connection as normal.
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');

var pool = new ConnectionPool(poolConfig, connectionConfig);

pool.requestConnection(function (err, connection) {
pool.acquire(function (err, connection) {
if(!err) {
var request = new Request('select 42', function(err, rowCount) {
assert.strictEqual(rowCount, 1);

// Release the connection back to the pool.
connection.close();
connection.release();
});

request.on('row', function(columns) {
assert.strictEqual(columns[0].value, 42);
});

connection.on('connect', function(err) {
connection.execSql(request);
});
connection.execSql(request);
}
});
```

When the connection is closed it is returned to the pool.
When the connection is released it is returned to the pool.
It is then available to be reused.

##Class: ConnectionPool

### new ConnectionPool(poolConfig, connectionConfig)

* `poolConfig` {Object}
* `poolConfig` {Object} the configuration for [generic-pool](https://github.com/coopernurse/node-pool) (see link for full list of arguments)
* `max` {Number} The maximum number of connections there can be in the pool. Default = `10`
* `min` {Number} The minimun of connections there can be in the pool. Default = `0`
* `idleTimeoutMillis` {Number} The Number of milliseconds before closing an unused connection. Default = `30000`

* `connectionConfig` {Object} The same configuration that would be used to [create a
tedious Connection](http://pekim.github.com/tedious/api-connection.html#function_newConnection).

### connectionPool.requestConnection(callback)
### connectionPool.acquire(callback)

* `callback` {Function} Callback function
* `error` {Error Object}
* `connection` {Object} A [Connection](http://pekim.github.com/tedious/api-connection.html)

### connectionPool.release(connection)

* `connection` {Object} A [Connection](http://pekim.github.com/tedious/api-connection.html)

### connectionPool.drain(callback)

* `callback` {Function} Callback function

##Class: PooledConnection
* An extension of the tedious [Connection](http://pekim.github.com/tedious/api-connection.html) object.

### connectionPool.release()

## 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() permenantly closes the connection (as close() behaves in in tedious).
107 changes: 35 additions & 72 deletions lib/connection-pool.js
Original file line number Diff line number Diff line change
@@ -1,86 +1,49 @@
var PooledConnection = require('./pooled-connection'),
PoolModule = require('generic-pool');

var connectionEventNames = [
'connect',
'end',
'debug',
'infoMessage',
'errorMessage',
'databaseChange',
'languageChange',
'charsetChange',
'secure'
];
'use strict';
var poolModule = require('generic-pool');
var PooledConnection = require('./pooled-connection');

function ConnectionPool(poolConfig, connectionConfig) {
var self = this,
param = {
name: poolConfig.name || "",
log: poolConfig.log,
create: function(callback) {
var connection = new PooledConnection(connectionConfig);
var connected = false;

connection.on('connect', function(err) {
if (connected) {
// The real 'connect' event has already been emmited by the
// connection, and processed in this function.
//
// This is now the fake connect event emmited by the acquire function,
// for applications' benefit.
return;
}

if (err) {
callback(err, null);
} else {
connected = true;
var self = this;

connection.on('release', function() {
connectionEventNames.forEach(function removeAllListeners(eventName) {
connection.removeAllListeners(eventName);
});

self.pool.release(connection);
});

callback(null, connection);
}
});
this.pool = poolModule.Pool({
name: poolConfig.name || "",
create: function (callback) {
var connection = new PooledConnection(self, connectionConfig);
connection.on('connect', function (err) {
if (err)
callback(err, null);
else
callback(null, connection);
});
},
destroy: function(connection) {
connection._close();
destroy: function (connection) {
if (!connection.isEnded) //con.close() calls pool.destroy(), which calls con.close() - isEnded stops looping
connection.close();
},
validate: function(connection) {
return !connection.closed && !connection.isEnded;
},
max: poolConfig.max || 10,
min: poolConfig.min || 0,
idleTimeoutMillis: poolConfig.idleTimeoutMillis || 30000
};

this.pool = PoolModule.Pool(param);
idleTimeoutMillis: poolConfig.idleTimeoutMillis || 30000,
log: poolConfig.log
});
}

module.exports = ConnectionPool;

ConnectionPool.prototype.acquire = function (callback) {
return this.pool.acquire(callback);
};

ConnectionPool.prototype.requestConnection = function(callback) {
var self = this;
this.pool.acquire(function(err, connection) {
if(err) {
callback(err, null);
}
else {
callback(null, connection);
connection.emit('connect');
}
});
ConnectionPool.prototype.release = function (connection) {
return this.pool.release(connection);
};

ConnectionPool.prototype.drain = function(callback) {
var self = this;
ConnectionPool.prototype.drain = function (callback) {
var self = this;

self.pool.drain(function() {
self.pool.destroyAllNow();
callback();
});
this.pool.drain(function () {
self.pool.destroyAllNow(callback);
});
};

module.exports = ConnectionPool;
26 changes: 15 additions & 11 deletions lib/pooled-connection.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
var Connection = require('tedious').Connection;
var util = require('util');

function PooledConnection(config) {
Connection.call(this, config);
}
function PooledConnection(connectionPool, config) {
var self = this;

util.inherits(PooledConnection, Connection);
this.connectionPool = connectionPool;
this.isEnded = false;

PooledConnection.prototype.close = function() {
this.emit('end');
this.emit('release'); //used by the pool
};
Connection.call(this, config);

this.on('end', function () {
self.isEnded = true;
self.connectionPool.pool.destroy(self);
});
}

PooledConnection.prototype = Object.create(Connection.prototype);

PooledConnection.prototype._close = function() {
return Connection.prototype.close.call(this);
PooledConnection.prototype.release = function () {
this.pool.release(this);
};

module.exports = PooledConnection;
47 changes: 39 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "tedious-connection-pool",
"version": "0.1.1",
"version": "0.2.1",
"description": "Connection Pool for tedious.",
"main": "lib/connection-pool.js",
"dependencies": {
"generic-pool": "2.0.4"
"generic-pool": "2.1.x"
},
"scripts": {
"test": "test"
Expand All @@ -18,18 +18,49 @@
"connection",
"pool"
],
"author": "Mike D Pilsbury",
"author": {
"name": "Mike D Pilsbury",
"email": "[email protected]"
},
"contributors": [
{
"name": "e11137",
"email": "[email protected]"
},
{
"name": "Ben Page",
"email": "[email protected]"
}
],
"maintainers": [
{
"name": "Mike D Pilsbury",
"email": "[email protected]"
},
{
"name": "Ben Page",
"email": "[email protected]"
}
],
"licenses": [
{
"type": "MIT",
"url": "https://github.com/brentertz/scapegoat/blob/master/LICENSE-MIT"
}
],
"license": "MIT",
"devDependencies": {
"tedious": "0.0.7",
"mocha": "1.6.0",
"async": "0.1.22"
"tedious": ">=0.0.7",
"mocha": ">=1.6.0",
"async": ">=0.1.22"
},
"licenses": "MIT",
"readmeFilename": "README.md",
"gitHead": "22e4053020343706eb9c998e9354263cf2ced759",
"bugs": {
"url": "https://github.com/pekim/tedious-connection-pool/issues"
},
"licenses": "MIT"
"homepage": "https://github.com/pekim/tedious-connection-pool",
"_id": "[email protected]",
"_shasum": "1be288bfd2da593b2111ec02efed508f95f1772b",
"_from": "..\\tedious-connection-pool"
}
Loading

0 comments on commit 7b88ee9

Please sign in to comment.