{"action":"created","issue":{"url":"https://api.github.com/repos/nodejs/node/issues/1239","labels_url":"https://api.github.com/repos/nodejs/node/issues/1239/labels{/name}","comments_url":"https://api.github.com/repos/nodejs/node/issues/1239/comments","events_url":"https://api.github.com/repos/nodejs/node/issues/1239/events","html_url":"https://github.com/nodejs/node/issues/1239","id":63595330,"number":1239,"title":"Breaking change: cluster connection behavior when between workers","user":{"login":"scottnonnenberg","id":443005,"avatar_url":"https://avatars.githubusercontent.com/u/443005?v=3","gravatar_id":"","url":"https://api.github.com/users/scottnonnenberg","html_url":"https://github.com/scottnonnenberg","followers_url":"https://api.github.com/users/scottnonnenberg/followers","following_url":"https://api.github.com/users/scottnonnenberg/following{/other_user}","gists_url":"https://api.github.com/users/scottnonnenberg/gists{/gist_id}","starred_url":"https://api.github.com/users/scottnonnenberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scottnonnenberg/subscriptions","organizations_url":"https://api.github.com/users/scottnonnenberg/orgs","repos_url":"https://api.github.com/users/scottnonnenberg/repos","events_url":"https://api.github.com/users/scottnonnenberg/events{/privacy}","received_events_url":"https://api.github.com/users/scottnonnenberg/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/nodejs/node/labels/cluster","name":"cluster","color":"f7c6c7"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-03-23T00:50:34Z","updated_at":"2015-08-27T18:01:45Z","closed_at":null,"body":"[Already reported this on node 0.12](https://github.com/joyent/node/issues/10427), thought I should report it here as well.\r\n\r\nOn OSX, I've noticed a big difference between the way that connections are dealt with by a master process when there are no workers ready to take care of that incoming connection. In node `0.10.36` (and before), the connection would be held open, and a worker that hadn't been started when that request was made would have the chance to handle it. In all versions of iojs (and node `0.12.0`), incoming connections when between workers are outright refused.\r\n\r\nAt the very least, this should be documented.\r\n\r\nExample code and output on both node `0.10.36` and iojs `1.6.1` follows:\r\n\r\n```javascript\r\nvar cluster = require('cluster');\r\nvar http = require('http');\r\nvar supertest = require('supertest');\r\nvar PORT = 3000;\r\n\r\n// cluster.schedulingPolicy = cluster.SCHED_NONE;\r\n\r\nif (!cluster.isMaster) {\r\n  http.createServer(function (req, res) {\r\n    if (req.url === '/error') {\r\n      setTimeout(function() {\r\n        throw new Error('something went wrong!');\r\n      }, 500);\r\n    }\r\n    else {\r\n      res.writeHead(200, {'Content-Type': 'text/plain'});\r\n      res.end('Hello World\\n');\r\n    }\r\n  }).listen(PORT);\r\n\r\n  console.log('Worker %s running at port %s', cluster.worker.id, PORT);\r\n}\r\nelse {\r\n  var count = 0;\r\n  var request = supertest('http://localhost:' + PORT);\r\n\r\n  var hitWorker = function(count) {\r\n    console.log('%s: Worker listening! Hitting it...', count);\r\n\r\n    request\r\n      .get('/error')\r\n      .expect(200, function(err, res) {\r\n        console.log('%s: Worker taken down, now making second request', count);\r\n\r\n        request\r\n          .get('/')\r\n          .expect('Hello World\\n')\r\n          .expect(200, function(err, res) {\r\n            console.log('%s: Second request complete. Error:', count, err);\r\n          });\r\n      });\r\n  };\r\n\r\n  cluster.on('disconnect', function() {\r\n    count +=1;\r\n    if (count < 2) {\r\n      cluster.fork();\r\n    }\r\n  });\r\n\r\n  cluster.on('listening', function() {\r\n    hitWorker(count);\r\n  });\r\n\r\n  // start just one worker\r\n  cluster.fork();\r\n\r\n  var interval = setInterval(function() {\r\n    console.log('...');\r\n  }, 1000);\r\n  interval.unref();\r\n}\r\n```\r\n\r\n## output\r\n\r\niojs 1.6.1 (scheduling policy does not make a difference):\r\n```\r\nWorker 1 running at port 3000\r\n0: Worker listening! Hitting it...\r\n/Users/scottnonnenberg/Development/thehelp/cluster/test.js:12\r\n        throw new Error('something went wrong!');\r\n              ^\r\nError: something went wrong!\r\n    at null._onTimeout (/Users/scottnonnenberg/Development/thehelp/cluster/test.js:12:15)\r\n    at Timer.listOnTimeout (timers.js:88:15)\r\n0: Worker taken down, now making second request\r\n0: Second request complete. Error: { [Error: connect ECONNREFUSED 127.0.0.1:3000]\r\n  code: 'ECONNREFUSED',\r\n  errno: 'ECONNREFUSED',\r\n  syscall: 'connect',\r\n  address: '127.0.0.1',\r\n  port: 3000 }\r\nWorker 2 running at port 3000\r\n1: Worker listening! Hitting it...\r\n...\r\n/Users/scottnonnenberg/Development/thehelp/cluster/test.js:12\r\n        throw new Error('something went wrong!');\r\n              ^\r\nError: something went wrong!\r\n    at null._onTimeout (/Users/scottnonnenberg/Development/thehelp/cluster/test.js:12:15)\r\n    at Timer.listOnTimeout (timers.js:88:15)\r\n1: Worker taken down, now making second request\r\n1: Second request complete. Error: { [Error: connect ECONNREFUSED 127.0.0.1:3000]\r\n  code: 'ECONNREFUSED',\r\n  errno: 'ECONNREFUSED',\r\n  syscall: 'connect',\r\n  address: '127.0.0.1',\r\n  port: 3000 }\r\n...\r\n```\r\n\r\nnode 0.10.36:\r\n```\r\nWorker 1 running at port 3000\r\n0: Worker listening! Hitting it...\r\n\r\n/Users/scottnonnenberg/Development/thehelp/cluster/test.js:13\r\n        throw new Error('something went wrong!');\r\n              ^\r\nError: something went wrong!\r\n    at null._onTimeout (/test.js:13:15)\r\n    at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)\r\n0: Worker taken down, now making second request\r\nWorker 2 running at port 3000\r\n1: Worker listening! Hitting it...\r\n0: Second request complete. Error: null\r\n...\r\n\r\n/Users/scottnonnenberg/Development/thehelp/cluster/test.js:13\r\n        throw new Error('something went wrong!');\r\n              ^\r\nError: something went wrong!\r\n    at null._onTimeout (/test.js:13:15)\r\n    at Timer.listOnTimeout [as ontimeout] (timers.js:112:15)\r\n1: Worker taken down, now making second request\r\n...\r\n...\r\n...\r\n...\r\n^C\r\n```\r\nThis version hangs, because third worker not started, and master keeps connection open. Note also that '0: second request complete' actually comes after '1: worker listening!'. This is because that initial second request actually ends up hitting the second worker. "},"comment":{"url":"https://api.github.com/repos/nodejs/node/issues/comments/135508251","html_url":"https://github.com/nodejs/node/issues/1239#issuecomment-135508251","issue_url":"https://api.github.com/repos/nodejs/node/issues/1239","id":135508251,"user":{"login":"Fishrock123","id":1093990,"avatar_url":"https://avatars.githubusercontent.com/u/1093990?v=3","gravatar_id":"","url":"https://api.github.com/users/Fishrock123","html_url":"https://github.com/Fishrock123","followers_url":"https://api.github.com/users/Fishrock123/followers","following_url":"https://api.github.com/users/Fishrock123/following{/other_user}","gists_url":"https://api.github.com/users/Fishrock123/gists{/gist_id}","starred_url":"https://api.github.com/users/Fishrock123/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fishrock123/subscriptions","organizations_url":"https://api.github.com/users/Fishrock123/orgs","repos_url":"https://api.github.com/users/Fishrock123/repos","events_url":"https://api.github.com/users/Fishrock123/events{/privacy}","received_events_url":"https://api.github.com/users/Fishrock123/received_events","type":"User","site_admin":false},"created_at":"2015-08-27T18:01:45Z","updated_at":"2015-08-27T18:01:45Z","body":"Hmm, does \r\n\r\n> Handles in the master process are now closed when the last worker\r\n  that holds a reference to them quits. Previously, they were only\r\n  closed at cluster shutdown.\r\n\r\nSound like this issue?"}}