Created
December 6, 2016 00:42
-
-
Save evantorrie/5746cbd5db6fbb65673c54dfa6b2337e to your computer and use it in GitHub Desktop.
Sample code that demonstrates uncollectible ClientRequests from keepAlive freeSockets
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
'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