Repository navigation
Closed
Labels
confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.macosIssues and PRs related to the macOS platform.Issues and PRs related to the macOS platform.netIssues and PRs related to the net subsystem.Issues and PRs related to the net subsystem.
Description
Ref: #1100
Ref: nodejs/node-v0.x-archive#16805
The following code will throw on OS X. It might take a while but it will happen. I usually see the error before runcount hits 2000.
'use strict';
const fork = require('child_process').fork;
const net = require('net');
const count = 12;
const port = 12346;
if (process.argv[2] === 'child') {
let sockets = [];
process.on('message', function(m, socket) {
function sendClosed(id) {
process.send({ id: id, status: 'closed'});
};
if (m.cmd === 'new') {
sockets.push(socket);
}
if (m.cmd === 'close') {
if (sockets[m.id].destroyed) {
throw new Error('socket already destroyed');
}
sockets[m.id].once('close', sendClosed.bind(null, m.id));
sockets[m.id].destroy();
}
if (m.cmd === 'clear') {
sockets = [];
}
});
} else {
const child = fork(process.argv[1], ['child']);
const server = net.createServer();
let sockets = [];
server.on('connection', function(socket) {
child.send({ cmd: 'new' }, socket);
sockets.push(socket);
if (sockets.length === count) {
closeSockets(0);
}
});
function createSockets() {
let j = count, client;
while (j--) {
client = net.connect(port, '127.0.0.1');
}
}
server.on('listening', function() {
createSockets();
});
let runCount = 0;
function closeSockets(i) {
if (i === count) {
console.log('run count: ' + ++runCount);
child.send({ cmd: 'clear' });
sockets = [];
return createSockets();
}
child.once('message', function(m) {
server.getConnections(function(err, num) {
closeSockets(i + 1);
});
});
child.send({ id: i, cmd: 'close' });
};
server.listen(port, '127.0.0.1');
}Metadata
Metadata
Assignees
Labels
confirmed-bugIssues and PRs for confirmed bugs.Issues and PRs for confirmed bugs.macosIssues and PRs related to the macOS platform.Issues and PRs related to the macOS platform.netIssues and PRs related to the net subsystem.Issues and PRs related to the net subsystem.
Activity
test: refactor to eliminate flaky test
brendanashworth commentedon Sep 4, 2015
@Trott any chance we could stick a loop inside the test? That way the error is easier to reproduce?
Trott commentedon Sep 6, 2015
@brendanashworth The code pasted above will run in an infinite loop until the bug is triggered. (Note the call to
createSockets()incloseSockets().) If you want to limit the number of times it runs, put in a check for the value ofrunCount.Ideally, it would be refactored in a way that would trip the bug without running over and over and over. But doing that would require knowing what is causing the bug...
Trott commentedon Sep 6, 2015
Although running it now, it's not throwing with the
throw()in the test code, it's now throwing withETIMEDOUTso ¯_(ツ)_/¯test: refactor to eliminate flaky test
test: refactor to eliminate flaky test
test: refactor to eliminate flaky test
test: refactor to eliminate flaky test
tnolet commentedon Sep 10, 2015
For anyone stumped with this: Just use this little web server and run it. Then start a simple apache bench. You will see the ab either fail or be really slow. I can reproduce this after running the test 2 or 3 times. This was with version 0.12.4. Downgrading to 0.10.40 fixed it.
run it:
evanlucas commentedon Feb 2, 2016
@Trott did this end up getting fixed? I know you had done a lot of work on it
Trott commentedon Feb 2, 2016
@evanlucas I haven't looked at this in months, but I did just run master branch against the test code in the original issue report. Still fails.
MylesBorins commentedon Feb 2, 2016
@Trott this is the exact same weirdness I was experiencing with the tests in #4819
The workaround is to watch for errors on stdin of the child process and handle them to avoid the throw.
https://github.com/nodejs/node/pull/4819/files#diff-e70e0e9b596132e4aa3b4bd4ced14515R60
Trott commentedon Feb 2, 2016
@thealphanerd That's right! I'm pretty sure that workaround is in a number of our tests.
Just to be clear so that no one sees that and closes this issue: This issue exists to document the actual bug. Users ideally shouldn't have to use a workaround that is basically "if you get an error, ignore it".
Trott commentedon Feb 2, 2016
Oh wait, I think I misunderstood you @thealphanerd. I may need to look at
that more closely...
On Tue, Feb 2, 2016 at 12:48 PM Myles Borins notifications@github.com
wrote:
Trott commentedon Feb 2, 2016
@thealphanerd I think these are different bugs, or at least the workaround for #4819 does not seem to work here. I can't find a way to catch an error on the child process's
stdin. The error here is thrown by thenet.connect()call.Although I do wonder if this specific issue might be a "not a bug" sort of issue. I just added some code to track the number of calls to
net.connect(). The script just crashed for me after 3 seconds. In that time, 2976 calls tonet.connect()happened. Even on the localhost interface, I'm inclined to give things a pass if opening 1000 connections a second on a four-year-old laptop causes anECONNRESETafter a few seconds.Thoughts?
Trott commentedon Jul 5, 2017
This now stalls out for me consistently after 1362 runs, after which I get
Error: connect ETIMEDOUT 127.0.0.1:12346. It sure looks like an OS-throttling issue or something like that rather than a Node.js issue. Closing. Feel free to comment or (if permitted by GitHub) re-open if you think it should stay open.