Skip to content

Commit

Permalink
Merge 1d4455d into 620bb51
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Sep 2, 2014
2 parents 620bb51 + 1d4455d commit 9c711a4
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
34 changes: 18 additions & 16 deletions lib/_http_agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,10 @@ function Agent(options) {
self.freeSockets = {};
self.keepAliveMsecs = self.options.keepAliveMsecs || 1000;
self.keepAlive = self.options.keepAlive || false;
// free keep-alive socket timeout. By default socket do not have a timeout.
// free keep-alive socket timeout. By default free socket do not have a timeout.
self.keepAliveTimeout = self.options.keepAliveTimeout || 0;
// working socket timeout. By default working socket do not have a timeout.
self.timeout = self.options.timeout || 0;
self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets;
self.maxFreeSockets = self.options.maxFreeSockets || 256;

Expand Down Expand Up @@ -102,16 +104,8 @@ function Agent(options) {
self.removeSocket(socket, options);
freeSockets.push(socket);

if (self.keepAliveTimeout) {
if (!socket._onKeepAliveTimeout) {
socket._onKeepAliveTimeout = function () {
this.destroy();
self.emit('timeout');
};
}
debug('enable free socket timer');
socket.setTimeout(self.keepAliveTimeout, socket._onKeepAliveTimeout);
}
// set free keepalive timer
socket.setTimeout(self.keepAliveTimeout);
}
} else {
self.removeSocket(socket, options);
Expand Down Expand Up @@ -170,11 +164,8 @@ Agent.prototype.addRequest = function(req, options) {
var socket = this.freeSockets[name].shift();
debug('have free socket');

// disable keep-alive timer
if (socket._onKeepAliveTimeout) {
debug('disable free socket timer');
socket.setTimeout(0, socket._onKeepAliveTimeout);
}
// restart the default timer
socket.setTimeout(this.timeout);

// don't leak
if (!this.freeSockets[name].length)
Expand Down Expand Up @@ -236,6 +227,15 @@ Agent.prototype.createSocket = function(req, options) {
}
s.on('close', onClose);

function onTimeout() {
debug('CLIENT socket onTimeout');
s.destroy();
self.emit('timeout');
}
s.once('timeout', onTimeout);
// set the default timer
s.setTimeout(self.timeout);

function onRemove() {
// We need this function for cases like HTTP 'upgrade'
// (defined by WebSockets) where we need to remove a socket from the
Expand All @@ -245,6 +245,8 @@ Agent.prototype.createSocket = function(req, options) {
s.removeListener('close', onClose);
s.removeListener('free', onFree);
s.removeListener('agentRemove', onRemove);
// remove timer
s.setTimeout(0, onTimeout);
}
s.on('agentRemove', onRemove);
return s;
Expand Down
5 changes: 5 additions & 0 deletions lib/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ function Agent(options) {
// default is keep-alive and 15s free socket timeout
options.keepAlive = options.keepAlive !== false;
options.keepAliveTimeout = options.keepAliveTimeout || 15000;
// default timeout is double keepalive timeout
if (options.timeout === undefined) {
options.timeout = options.keepAliveTimeout * 2;
}

OriginalAgent.call(this, options);

var self = this;
Expand Down
29 changes: 29 additions & 0 deletions test/agent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,10 +491,12 @@ describe('agent.test.js', function () {
});

it('should free socket timeout', function (done) {
done = pedding(2, done);
var name = 'localhost:' + port + '::';
var agent = Agent({
keepAliveTimeout: 1000,
});
agent.on('timeout', done);
var lastPort = null;
http.get({
agent: agent,
Expand Down Expand Up @@ -525,6 +527,33 @@ describe('agent.test.js', function () {
agent.sockets[name].should.length(1);
});

it('should working socket timeout', function (done) {
done = pedding(2, done);
var name = 'localhost:' + port + '::';
var agent = Agent({
keepAliveTimeout: 1000,
});
agent.on('timeout', done);
var lastPort = null;
http.get({
agent: agent,
port: port,
path: '/hang',
}, function (res) {
throw new Error('should not run this');
}).on('error', function (err) {
should.exist(err);
// socket.destroy();
err.message.should.equal('socket hang up');
err.code.should.equal('ECONNRESET');
agent.sockets.should.not.have.key(name);
done();
});
should.exist(agent);
agent.sockets.should.have.key(name);
agent.sockets[name].should.length(1);
});

it('should destroy free socket before timeout', function (done) {
var name = 'localhost:' + port + '::';
var agent = new Agent({
Expand Down

0 comments on commit 9c711a4

Please sign in to comment.