public
Last active

Adding keep alive for https connections

  • Download Gist
gistfile1.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
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;
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.