Permalink
Browse files

Fixes race condition in PooledConnection.shutdown()

Previously, if PooledConnection.shutdown() was called before the connection process had completed,
_closeConnections would only call ConnectionInPool.close() on each connection in the pool if that
ConnectionInPool had connected == true. If the connection process was still in-progress, connected
would be set to false, close() would not be called, and the socket would later connect, causing tests
to hang.

This adds two events to ConnectionInPool, 'connected' and 'disconnected' - 'disconnected' is not
actually needed, just added for symmetry. Instead of setting ConnectionInPool.connected directly,
call setConnected() or setDisconnected() and the appropriate event will be emitted.

ConnectionInPool.closeConnections now attaches an on('connected') handler to close the connection
if the connection completes after shutdown() has been called.
  • Loading branch information...
robert-chiniquy committed May 29, 2012
1 parent 1a62b66 commit 851479771e0dfd58db56b198c911524df65b2bed
Showing with 33 additions and 2 deletions.
  1. +21 −2 lib/driver.js
  2. +12 −0 test/test_driver.js
View
@@ -493,12 +493,28 @@ ConnectionInPool.prototype.connect = function(callback) {
}
Connection.call(this, this._options);
Connection.prototype.connect.call(this, function(err) {
self.connected = !err;
if (err) {
self.setDisconnected();
}
else {
self.setConnected();
}
self.unhealthyAt = err ? new Date().getTime() : 0;
callback(err);
});
};
ConnectionInPool.prototype.setConnected = function() {
this.connected = true;
this.emit('connected');
};
ConnectionInPool.prototype.setDisconnected = function() {
this.connected = false;
this.emit('disconnected');
};
ConnectionInPool.prototype.isHealthy = function() {
return this.unhealthyAt === 0;
}
@@ -596,7 +612,7 @@ PooledConnection.prototype._incr = function() {
} else if (this.connections[this.current_node].isStaleUnhealthy()) {
// unhealthy and stale, so let reset the node (appears as if unconnected).
this.connections[this.current_node].taken = false;
this.connections[this.current_node].connected = false;
this.connections[this.current_node].setDisconnected();
this.connections[this.current_node].unhealthyAt = 0;
break;
} else {
@@ -808,6 +824,9 @@ PooledConnection.prototype._closeConnections = function(closeCallback) {
if (con.connected) {
con.close(cb);
} else {
con.on('connected', function() {
con.close(cb);
});
cb(null);
}
}, function(err) {
View
@@ -1118,3 +1118,15 @@ exports.testPooledConnectionShutdownTwice = function(test, assert) {
secondCbCalledImmediatelyWithError = true;
});
};
exports.testPooledContainerImmediateShutdown = function(test, assert) {
var hosts = ['127.0.0.1:9160'];
var pool = new PooledConnection({'hosts': hosts, 'keyspace': 'Keyspace1'});
pool.connect();
pool.shutdown(function(err) {
assert.ifError(err);
test.finish();
});
};

0 comments on commit 8514797

Please sign in to comment.