diff --git a/README.md b/README.md index 5c54f54..421527a 100644 --- a/README.md +++ b/README.md @@ -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'); @@ -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) { @@ -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 @@ -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() @@ -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). \ No newline at end of file diff --git a/lib/connection-pool.js b/lib/connection-pool.js index fb7b133..426787f 100644 --- a/lib/connection-pool.js +++ b/lib/connection-pool.js @@ -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 }; @@ -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(); @@ -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; @@ -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); @@ -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; } } @@ -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); } @@ -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) { diff --git a/package.json b/package.json index 4dbfc35..70af7af 100644 --- a/package.json +++ b/package.json @@ -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": { @@ -42,7 +42,7 @@ } ], "devDependencies": { - "tedious": ">=1.7.0", + "tedious": ">=1.8.0", "mocha": ">=1.6.0" }, "licenses": "MIT", diff --git a/test/load-test.js b/test/load-test.js index e5ec7fe..be3b0b5 100644 --- a/test/load-test.js +++ b/test/load-test.js @@ -17,7 +17,7 @@ var p = 0; var createRequest = function (err, connection) { if (err) - console.err(err); + console.error(err); if (c >= total) return;