I am trying to create a platform for automatically deploying the applications that I create in NodeJS. Each application can be started and stopped from the control panel that processes these operations. The control panel performs the following actions when the application starts:
- It will request a handle from the binder port, which runs as root. This binder is a forked child of the control panel.
- Now the control panel listens for requests on this port. After receiving the request, it sends a client socket handle to the application that listens for the message event for new requests.
- When the application is signaled, the control panel frees all control over the request and the socket.
- The application does what it needs and releases and closes the request and socket.
This setup works well unless you are trying to bring down a server that is no longer required. Although the server throws a close event, it still accepts the connection, which eventually ends because there is no longer a link to the request.
I assume that there is a handle that is not released properly and thus prevents the server from waking up.
Port Binding:
var options = { http: require('http'), https: require('https') }; process.on('message',function( data, handle ) { var port = data.port, type = data.type, server; server = options[type].createServer(); server.once('error', function( err ) { process.send({success: false, port: port, error: err}); }); server.listen(port,function(){ var handle = server._handle; process.send({success: true, port: port}, handle); server.close(); handle.close(); server._handle = null; handle = null; server.removeAllListeners(); }); });
Control Panel:
var cp = require('child_process'), app, types = { http: require('http'), https: require('https') }, binder = cp.fork('./portbinder'); binder.on('message', function( data, handle ) { var server = types['http'].createServer(handler); server.once('close', function() { server._handle = null; handle = null; }); server.listen( handle ); }); function handler( req, resp ) { app = app || cp.fork('./application'), socket = resp.socket, _handle = socket._handle, _req = {}, _resp = {}, _socket = {}; // Copy transferable fields. for( i in req ) { if( typeof req[i] != 'function' && i != 'socket' && i != 'connection' && i != 'client' ) { _req[i] = req[i]; } } for( i in resp ) { if( typeof resp[i] != 'function' && i != 'socket' && i != 'connection' && i != 'client' ) { _resp[i] = resp[i]; } } for( i in socket ) { if( typeof socket[i] != 'function' && i != '_handle' && i != '_httpMessage' && i != '_idlePrev' && i != '_idleNext' && i != 'server' ) { _socket[i] = socket[i]; } } // Send request to application. app.send({ type: 'request', data: { req: _req, resp: _resp, socket: _socket } }, _handle ); // Release the handle here without sending anything to the browser. socket._write = function() {}; resp.end(); socket.destroy(); socket._handle = null; _handle = null; };
Application:
function reattach( target, properties ) { var i; for( i in properties ) { target[i] = properties[i]; } return target; }; function handler( req, resp ) { resp.end('hello world!'); }; process.on('message', function( param, handle ) { var _req = param.data.req, _resp = param.data.resp, _socket = param.data.socket, socket, resp, req;
As you can see, I am trying to remove and delete all the _handle properties that I have, but the server handle does not stop listening on the port. When I create the control panel, there is an uncaught exception, it will work, and the connecting device will also do this. But the node application process does not shut down, and the port remains connected, so I explain that Iβm not releasing something there, but I canβt find it.
The whole setup works, it just doesn't shut down the server when I ask for it.
EDIT: I should probably note that I'm using node.js v0.5.10