Skip to content

Instantly share code, notes, and snippets.

@evantorrie
Created December 6, 2016 00:42
Show Gist options
  • Save evantorrie/5746cbd5db6fbb65673c54dfa6b2337e to your computer and use it in GitHub Desktop.
Save evantorrie/5746cbd5db6fbb65673c54dfa6b2337e to your computer and use it in GitHub Desktop.
Sample code that demonstrates uncollectible ClientRequests from keepAlive freeSockets
'use strict';
const heapdump=require('heapdump');
const assert = require('assert');
const http = require('http');
const PORT=8089;
const kMaxUsedSockets=10;
const kMaxFreeSockets=9;
const agent = new http.Agent({
keepAlive: true,
keepAliveMsecs: 1000,
maxSockets: kMaxUsedSockets,
maxFreeSockets: kMaxFreeSockets
});
var buffer=new Buffer(1000000);
buffer.fill('h');
const server = http.createServer(function(req, res) {
res.write(buffer, () => res.end() );
});
function get(path, callback) {
console.log(`Making request to ${path}`);
return http.get({
host: 'localhost',
port: PORT,
agent: agent,
path: path
}, callback);
}
const name = 'localhost:' + PORT + ':';
function checkSockets(used, free) {
assert.equal(agent.sockets[name] ? agent.sockets[name].length : undefined, used);
assert.equal(agent.freeSockets[name] ? agent.freeSockets[name].length : undefined, free);
}
function makeRequests(cb) {
// Make kMaxUsedSOckets concurrent requests
let initiated = 0;
let freed = 0;
let destroyed = 0;
for (let i = 0; i < kMaxUsedSockets; ++i) {
let reqNum = i;
let req = get(`/buf?req=${reqNum}`, function(res) {
res.data = '';
assert.equal(res.statusCode, 200);
res.on('data', body => res.data += body );
res.on('end', function() {
console.log(`Received response of size ${res.data.length} for req ${reqNum}`);
let freeSock = agent.freeSockets[name] ? agent.freeSockets[name].length : agent.freeSockets[name];
checkSockets(initiated-freed, freeSock);
});
});
req.on('socket', s => {
initiated++;
s.once('free', (s) => {
freed++;
console.log('socket freed at ', Date.now());
if (Math.min(kMaxFreeSockets,freed) + destroyed === kMaxUsedSockets) { cb(); }
});
s.once('close', (s) => {
destroyed++;
console.log('socket closed at ', Date.now());
if (Math.min(kMaxFreeSockets,freed) + destroyed === kMaxUsedSockets) { cb(); }
});
});
}
checkSockets( kMaxUsedSockets, undefined );
}
server.listen(PORT, function() {
// request first, and keep alive
heapdump.writeSnapshot(function(err, fn) {
console.log(`BEGIN: heapsnapshot written to ${fn}`);
});
makeRequests(() => {
checkSockets( undefined, kMaxFreeSockets);
heapdump.writeSnapshot(function(err, fn) {
console.log(`END: heapsnapshot written to ${fn}`);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment