-
Notifications
You must be signed in to change notification settings - Fork 439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
connection pooler #43
Conversation
Thank you, this looks interesting. It slightly worries me that Connection's api is duplicated in ConnectionPooler. This would be a maintenance overhead; any changes to Connection's api would have to be reflected in ConnectionPooler. However my bigger concern is that the implementation simply may not work. It looks to me like a connection is acquired from the pool for each request. If that is the case, then some requests will not work. For example, you cannot begin and end a transaction on different connections. Have you tested this sort of thing? That brings me on to testing. I'd like to see integration tests, exercising all of ConnectionPooler's function. Sorry if this all seems a bit negative. I don't want to discourage contributions. |
Hi, https://github.com/e11137/TediousPooler.git thanks |
It's the version of connection.coffee at https://github.com/e11137/tedious/blob/master/src/connection.coffee, with the emmision of SENT_CLIENT_REQUEST:
name: 'SentClientRequest'
exit:->
@reusable = true
events:
socketError: (error) ->
@transitionTo(@STATE.FINAL)
data: (data) ->
@sendDataToTokenStreamParser(data)
message: ->
sqlRequest = @request
@request = undefined
sqlRequest.callback(sqlRequest.error, sqlRequest.rowCount)
@transitionTo(@STATE.LOGGED_IN) Moving the state transition to the end of the Moving it back to the start of the event, all tests pass again. SENT_CLIENT_REQUEST:
name: 'SentClientRequest'
exit:->
@reusable = true
events:
socketError: (error) ->
@transitionTo(@STATE.FINAL)
data: (data) ->
@sendDataToTokenStreamParser(data)
message: ->
@transitionTo(@STATE.LOGGED_IN)
sqlRequest = @request
@request = undefined
sqlRequest.callback(sqlRequest.error, sqlRequest.rowCount) |
I have an error when I move it back.
you can reproduce this error with this code. var ConnectionPooler = require('../lib/tedious').ConnectionPooler;
var Request = require('../lib/tedious').Request;
var config = {
server: '192.168.1.212',
userName: 'test',
password: 'test'
}
var pooler = new ConnectionPooler(config);
for(i=0;i<15;i++)
pooler.execute(function(connection){
var request = new Request("select 42, 'hello world'", function(err, rowCount) {
if (err) {
console.log(err);
} else {
console.log("Pooler "+rowCount + ' rows');
}
});
request.on('done', function(rowCount, more) {
console.log(rowCount + ' rows returned');
});
connection.execSql(request)
});
|
The state machine has to be in the correct state before calling the request's completion callback. The API allows another request to be made on the connection as soon as the callback is called. If the state machine is not put in to the correct state before the request completion callback is called, then initiating another request on the connection during the callback would fail (as there's code to detect when the connection is not in a suitable state). I could swap the execution order, to call the callback first. I'd then have to change the documentation to reflect this. This would force any code that needs to initiate another request on the completion of a request, to defer the new request to the next tick. I don't want to do this unless we have to. I'd prefer to keep the current execution order, and work out why this breaks the pooler code. Then fix either tedious or the pooler (or generic-pool) once the problem is better understood. At the moment I'm baffled about what's causing the problem, as the pooler code looks perfectly reasonable. I think I'm going to have to scatter some |
TediousPooler.prototype.execute = function(callback) {
var self = this;
this.pool.acquire(function(err, connection) {
if(err) {
self.looger.log("TediousPooler :"+err,'error');
}
else {
callback(connection);
self.pool.release(connection);
}
});
} The connection is released back in to the pool (and is therefore available for re-use) as soon as the callback has been called. If I'm reading the code correctly there is no guarantee, in fact it's very unlikely, that the request on the connection has completed at that point. So putting the connection back in to the pool, and then immediately calling I added some log statements in TediousPooler, and this does seem to be what is happening. It is reusing the same connection for every request, even though it hasn't completed the first request. |
Hi, My first exemple use var ConnectionPooler declared in https://github.com/e11137/tedious/blob/master/src/connection-Pooler.coffee (I need to change the emition of reusable event to create: (callback) ->
connection = new Connection(config)
connection.on('connect', (err) ->
console.log('connected')
if !err
callback(null, connection)
connection.on('reusable', () ->
_this.pool.release(connection)
)
) I need to change the emission of reusable event to allow multiple requests in the same callback and only emit one event at the end. |
I've been thinking about your approach to the pooling, and I'm not sure that it's going to be easy to make it work. As you say, the tedious API will need to change to allow batches of requests to execute, and only emit one I've been considering an alternative (slightly more conventional) approach, which does not require any changes to tedious. The pooling implementation manages the allocation of Connections. The application requests a connection from the pool, and uses it with the existing API, executing as many requests against the Connection as it wants. When it's finished its work, it calls the I've knocked together an implementation to illustrate this approach. It's at https://github.com/pekim/tedious-connection-pool. |
Connection pooling is now a separate project, tedious-connection-pool. |
Hi,
thanks for your excellent work.
I have integrated a connection poller based on generic-pool " https://github.com/coopernurse/node-pool".
may be It can be merged ?
thanks
Best regards