Skip to content

Commit

Permalink
Add support for pool exhaustion, and eventually processing queued con…
Browse files Browse the repository at this point in the history
…nection requests.
  • Loading branch information
pekim committed Oct 7, 2012
1 parent f468f02 commit 592e42f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 13 deletions.
47 changes: 39 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
var Connection = require('tedious').Connection;
var util = require('util');

var connectionEventNames = [
'connect',
'end',
'debug',
'infoMessage',
'errorMessage',
'databaseChange',
'languageChange',
'charsetChange',
'secure'
];

function PooledConnection(pool, config) {
Connection.call(this, config);
this.pool = pool;
Expand All @@ -10,7 +22,7 @@ util.inherits(PooledConnection, Connection);

PooledConnection.prototype.close = function() {
this.emit('end');
this.pool.connectionAvailable(this);
this.pool.returnConnectionToPool(this);
}

PooledConnection.prototype._close = function() {
Expand All @@ -21,35 +33,54 @@ function ConnectionPool(poolConfig, connectionConfig) {
var pool = this;

pool.config = poolConfig;
pool.requestNumber = 0;
pool.stats = {
maxSize: poolConfig.maxSize,
connections: 0
};
pool.inUseConnections = [];
pool.availableConnections = [];
pool.pendingConnectionRequests = [];

pool.connectionAvailable = function(connection) {
this.inUseConnections.splice(this.inUseConnections.indexOf(connection), 1);
pool.returnConnectionToPool = function(connection) {
connectionEventNames.forEach(function removeAllListeners(eventName) {
connection.removeAllListeners(eventName);
});

pool.inUseConnections.splice(pool.inUseConnections.indexOf(connection), 1);

if (pool.pendingConnectionRequests.length > 0) {
var pendingConnectionRequest = pool.pendingConnectionRequests.shift();

pendingConnectionRequest(connection);
}
};

pool.requestConnection = function(callback) {
var requestNumber = ++pool.requestNumber;
var connection;

if (pool.availableConnections.length > 1) {
if (pool.availableConnections.length > 0) {
connection = availableConnections.shift();
connection.emit('connect');
} else if (pool.inUseConnections.length < pool.config.maxSize) {
connection = new PooledConnection(pool, connectionConfig);
connection.number = ++pool.stats.connections;
}

if (connection) {
useConnection(connection);
} else {
pool.pendingConnectionRequests.push(useConnection);
pool.pendingConnectionRequests.push(function (connection) {
useConnection(connection);
connection.emit('connect');
});
}

function useConnection(connection) {
pool.inUseConnections.push(connection);

process.nextTick(function() {
callback(connection);
});
callback(connection);
}
};

Expand Down
32 changes: 27 additions & 5 deletions test/connection-pool.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ var connectionConfig = {
userName: 'test',
password: 'test',
server: '192.168.1.212',
// options: {
// debug: {
// packet: true,
// data: true,
// payload: true,
// token: true
// }
// }
};

describe('ConnectionPool', function() {
Expand All @@ -24,22 +32,36 @@ describe('ConnectionPool', function() {

describe('multiple connections within pool maxSize', function() {
var poolConfig = {maxSize: 5};
var numberOfConnectionsToUse = poolConfig.maxSize;

it('should connect, and end', function(done) {
testPool(poolConfig, poolConfig.maxSize, requestConnectionAndClose, done);
testPool(poolConfig, numberOfConnectionsToUse, requestConnectionAndClose, done);
});

it('should connect, select, and end', function(done) {
testPool(poolConfig, poolConfig.maxSize, requestConnectionSelectAndClose, done);
testPool(poolConfig, numberOfConnectionsToUse, requestConnectionSelectAndClose, done);
});
});

describe('connections exceed pool maxSize', function() {
var poolConfig = {maxSize: 5};
var numberOfConnectionsToUse = 20;

it('should connect, and end', function(done) {
testPool(poolConfig, numberOfConnectionsToUse, requestConnectionAndClose, done);
});

it('should connect, select, and end', function(done) {
testPool(poolConfig, numberOfConnectionsToUse, requestConnectionSelectAndClose, done);
});
});
});

function testPool(poolConfig, numberOfConnectionsToUse, useConnectionfunction, done) {
function testPool(poolConfig, numberOfConnectionsToUse, useConnectionFunction, done) {
var pool = new ConnectionPool(poolConfig, connectionConfig);

function doIt(done) {
useConnectionfunction(pool, function() {
useConnectionFunction(pool, function() {
done();
});
}
Expand All @@ -61,7 +83,7 @@ function requestConnectionAndClose(pool, done) {
connection.on('end', function(err) {
done();
});
});
} );
}

function requestConnectionSelectAndClose(pool, done) {
Expand Down

0 comments on commit 592e42f

Please sign in to comment.