Created
April 9, 2012 21:54
-
-
Save Jimbly/2346805 to your computer and use it in GitHub Desktop.
Adding keep alive for https connections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function addKeepAliveTimeout(agent) { | |
function fail(msg) { | |
console.warn(msg + ', node version: ' + process.version); | |
return agent; | |
} | |
// Check it's what we expect | |
var old_listeners = agent.listeners('free'); | |
if (!old_listeners || old_listeners.length !== 1) { | |
return fail('Unexpected lacking "free" listener'); | |
} | |
var expected_listener = | |
'function (socket, host, port) {\n' | |
+ ' var name = host + \':\' + port;\n' | |
+ ' if (self.requests[name] && self.requests[name].length) {\n' | |
+ ' self.requests[name].shift().onSocket(socket);\n' | |
+ ' if (self.requests[name].length === 0) {\n' | |
+ ' // don\'t leak\n' | |
+ ' delete self.requests[name];\n' | |
+ ' }\n' | |
+ ' } else {\n' | |
+ ' // If there are no pending requests just destroy the\n' | |
+ ' // socket and it will get removed from the pool. This\n' | |
+ ' // gets us out of timeout issues and allows us to\n' | |
+ ' // default to Connection:keep-alive.\n' | |
+ ' socket.destroy();\n' | |
+ ' }\n' | |
+ ' }'; | |
var expected_addRequest = | |
'function (req, host, port) {\n' | |
+ ' var name = host + \':\' + port;\n' | |
+ ' if (!this.sockets[name]) {\n' | |
+ ' this.sockets[name] = [];\n' | |
+ ' }\n' | |
+ ' if (this.sockets[name].length < this.maxSockets) {\n' | |
+ ' // If we are under maxSockets create a new one.\n' | |
+ ' req.onSocket(this.createSocket(name, host, port));\n' | |
+ ' } else {\n' | |
+ ' // We are over limit so we\'ll add it to the queue.\n' | |
+ ' if (!this.requests[name]) {\n' | |
+ ' this.requests[name] = [];\n' | |
+ ' }\n' | |
+ ' this.requests[name].push(req);\n' | |
+ ' }\n' | |
+ '}'; | |
if (old_listeners[0].toString() !== expected_listener) { | |
console.log(require('util').inspect(old_listeners[0].toString())); | |
return fail('Listener not defined as expected'); | |
} | |
if (agent.addRequest.toString() !== expected_addRequest) { | |
console.log(require('util').inspect(agent.addRequest.toString())); | |
return fail('addRequest not defined as expected'); | |
} | |
console.log('Using wrapped listener agent'); | |
assert.ok(!agent.free_sockets); // We're adding this field | |
// Remove old listener | |
agent.removeAllListeners('free'); | |
agent.free_sockets = {}; | |
agent.on('free', function(socket, host, port) { | |
var name = host + ':' + port; | |
if (agent.requests[name] && agent.requests[name].length) { | |
agent.requests[name].shift().onSocket(socket); | |
if (agent.requests[name].length === 0) { | |
// don't leak | |
delete agent.requests[name]; | |
} | |
} else { | |
// save the socket for at least a little while | |
var obj = { | |
socket: socket | |
}; | |
obj.timeout_id = setTimeout(function() { | |
var idx = agent.free_sockets[name].indexOf(obj); | |
Assert.ok(idx !== -1); | |
agent.free_sockets[name].splice(idx, 1); | |
if (!agent.free_sockets[name].length) { | |
delete agent.free_sockets[name]; | |
} | |
socket.destroy(); | |
}, 10000); | |
if (!agent.free_sockets[name]) { | |
agent.free_sockets[name] = []; | |
} | |
agent.free_sockets[name].push(obj); | |
} | |
}); | |
agent.addRequest = function(req, host, port) { | |
var name = host + ':' + port; | |
if (this.free_sockets[name] && this.free_sockets[name].length) { | |
// Has a free socket, use it | |
var obj = this.free_sockets[name].shift(); | |
clearTimeout(obj.timeout_id); | |
req.onSocket(obj.socket); | |
} else { | |
if (!this.sockets[name]) { | |
this.sockets[name] = []; | |
} | |
if (this.sockets[name].length < this.maxSockets) { | |
// If we are under maxSockets create a new one. | |
req.onSocket(this.createSocket(name, host, port)); | |
} else { | |
// We are over limit so we'll add it to the queue. | |
if (!this.requests[name]) { | |
this.requests[name] = []; | |
} | |
this.requests[name].push(req); | |
} | |
} | |
}; | |
return agent; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment