Created
December 5, 2012 22:06
-
-
Save dannycoates/4219937 to your computer and use it in GitHub Desktop.
Of nextTicks and sockets
This file contains 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
var http = require('http') | |
var server = http.createServer(function (req, res) { | |
res.writeHead(200, {'Content-Type': 'text/plain'}) | |
res.end('Hello World\n') | |
}).listen(1337) | |
var agent = new http.Agent({maxSockets: 1}) | |
agent.on('free', function (socket, host, port) { | |
console.log('freeing socket. destroyed? ', socket.destroyed) | |
}) | |
var requestOptions = { agent: agent, host: 'localhost', port: 1337, path: '/' } | |
var request1 = http.get( | |
requestOptions, | |
function (response) { | |
// assert request2 is queued in the agent | |
console.assert(agent.requests['localhost:1337'].length === 1) | |
console.log('got response1') | |
request1.socket.on( | |
'close', | |
function () { | |
console.log('request1 socket closed') | |
} | |
) | |
response.pipe(process.stdout) | |
response.on( | |
'end', | |
function () { | |
console.log('response1 done') | |
///////////////////////////////// | |
// | |
// THE IMPORTANT PART | |
// | |
// It is possible for the socket to get destroyed and other work | |
// to run before the 'close' event fires because it happens on | |
// nextTick. This example is contrived because it destroys the | |
// socket manually at just the right time, but at Voxer we have | |
// seen cases where the socket is destroyed by non-user code | |
// then handed out again by an agent *before* the 'close' event | |
// is triggered. | |
request1.socket.destroy() | |
process.nextTick( | |
function () { | |
// assert request2 was removed from the queue | |
console.assert(!agent.requests['localhost:1337']) | |
console.log("waiting for request2.onSocket's nextTick") | |
process.nextTick( | |
function () { | |
// assert that the same socket is assigned to request2 | |
console.assert(request1.socket === request2.socket) | |
console.assert(!request2.socket.destroyed, 'the socket is destroyed') | |
} | |
) | |
} | |
) | |
} | |
) | |
} | |
) | |
var request2 = http.get( | |
requestOptions, | |
function (response) { | |
console.assert(!request2.socket.destroyed) | |
// assert reusing the same socket | |
console.assert(request1.socket === request2.socket) | |
console.log('got response2') | |
request2.socket.on( | |
'close', | |
function () { | |
console.log('request2 socket closed') | |
} | |
) | |
response.pipe(process.stdout) | |
response.on('end', function () { | |
console.log('response2 done') | |
}) | |
} | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment