Skip to content

Instantly share code, notes, and snippets.

@stolsma
Created August 12, 2011 16:19
Show Gist options
  • Save stolsma/1142394 to your computer and use it in GitHub Desktop.
Save stolsma/1142394 to your computer and use it in GitHub Desktop.
carapace-haibu net.js test code to understand the port bind errors....
/*
* net.js: Wrapper around node.js core `net` module for observing relevant events
*
* (C) 2011 Nodejitsu Inc.
*
*/
var net = require('net'),
binding = process.binding('net'),
carapace = require('./carapace');
var dummyFD = null,
socket = binding.socket,
listen = binding.listen;
//
// Helper function from Node code to parse port arguments
// passed to net.prototype.Server.listen
//
function toPort(x) {
return (x = Number(x)) >= 0 ? x : false;
}
//
// ### function nextPort (port)
// #### @port {Number} Port to increment from.
// Gets the next port in sequence from the
// specified `port`.
//
function nextPort (port) {
return port
? port + 1
: 8000;
};
//
// Helper function from node.js core for
// working with `dummyFD`
//
function getDummyFD () {
if (!dummyFD) {
try { dummyFD = socket('tcp') }
catch (e) { dummyFD = null }
}
}
//
// Internal mapping of server instances to
// ports that have been mapped via `.listen()`.
//
carapace.servers = {}
// carapace.on('proxy::list', function (done) {
// done(carapace.proxy.ports);
// });
//
// Separate since net.Server uses a cached bind function
//
net.Server.prototype._doListen = function () {
var self = this,
desired = toPort(arguments[0]),
ip = arguments[1],
actual;
self.fd = socket(self.type);
// Ensure we have a dummy fd for EMFILE conditions.
getDummyFD();
find_port:
for(;;) {
try {
binding.bind(self.fd, desired, arguments[1]);
break find_port;
}
catch (err) {
//
// If this is not an `EADDRINUSE` error or the port is in
// `carapace.ports.throw` which should always throw an error,
// then throw the error.
//
if (err.code !== 'EADDRINUSE' || carapace.ports.throw.indexOf(desired) !== -1) {
self.close();
return self.emit('error', err);
}
desired = nextPort(desired);
}
}
actual = this.address().port;
if (!desired) {
desired = actual;
}
//
// Need to the listening in the nextTick so that people potentially have
// time to register 'listening' listeners.
//
return process.nextTick(function() {
//
// It could be that server.close() was called between the time the
// original listen command was issued and this. Bail if that's the case.
// See test/simple/test-net-eaddrinuse.js
//
if (typeof self.fd !== 'number') return;
try {
listen(self.fd, self._backlog || 128);
//
// Store the server that has listened on the `desired` port
// on the carapace itself, indexed by port.
//
carapace.servers[desired] = self;
//
// If the desired port is not in union of `carapace.ports.throw`,
// and `carapace.ports.ignore` then emit the `carapace::port` event.
//
// Remark: How does this work with multi-server programs?
//
if (carapace.ports.throw.concat(carapace.ports.ignore).indexOf(actual) === -1) {
carapace.emit('carapace::port', {
id: carapace.id,
desired: desired,
port: actual
});
}
}
catch (err) {
if (err.code === 'EADDRINUSE') {
self._doListen(actual + 1, ip);
}
else {
self.close();
self.emit('error', err);
}
return
}
self._startWatcher();
});
};
@stolsma
Copy link
Author

stolsma commented Aug 12, 2011

Added line 67 and changed line 134-141

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment