Dirty procedure for dealing restart event #10

Closed
bloodmage opened this Issue Jul 11, 2011 · 0 comments

Comments

Projects
None yet
2 participants

when process exit, this command will be executed:

children.splice(i, 1);

this will change the order in children (shift higher order ones left), and after that, if restarts,

children[i] = childProcess.spawn(

will overwrite existing process, thus make process leak from the array ( and shorten length of array till 1 )

A fix is that change children into a object ( children = {}; )
This is my version of restart, it will work until "tid" becomes sufficiently big ( not likely to happen )

    isMaster = true;
    emitter.id = "master";
    var children = {}, tcpDescriptor;
    var tid = 1;
    if (typeof(options.port)=='string')
    {
        tcpDescriptor = netBinding.socket("unix");
        netBinding.bind(tcpDescriptor, options.port);
    }
    else
    {
        tcpDescriptor = netBinding.socket("tcp4");
        netBinding.bind(tcpDescriptor, options.port || 80, options.host || '0.0.0.0');
    }
    netBinding.listen(tcpDescriptor, 128);
    var masterListen = options.masterListen !== false;
    var numChildren = (options.nodes || 1) - (masterListen ? 1 : 0);
    if(masterListen){
        server.listenFD(tcpDescriptor, 'tcp4');
    }
    var priorArgs = process.argv;
    if(process.platform == "cygwin" && priorArgs){
        priorArgs = ["/usr/bin/bash","--login","-c", "cd " + process.cwd() + " && " + priorArgs.join(" ")];
    }
    var env = {};
    for(var i in process.env){
        env[i] = process.env[i];
    }
    var createChild = function(i){
        var childConnection = netBinding.socketpair();
        env._CHILD_ID_ = "child-" + i;
        // spawn the child process
        var child = children[i] = childProcess.spawn(
            priorArgs[0],
            priorArgs.slice(1),
            env,
            [childConnection[1], 1, 2]
        );
        child.master = new net.Stream(childConnection[0], 'unix');

        child.master.write("tcp", "ascii", tcpDescriptor);
        (function(child){
            for(var j in children){
                    var siblingConnection = netBinding.socketpair();
                    child.master.write("sibling", "ascii", siblingConnection[1]);
                    children[j].master.write("sibling", "ascii", siblingConnection[0]);
            }
            var masterChildConnection = netBinding.socketpair();
            process.nextTick(function(){
                var stream = new net.Stream(masterChildConnection[0], "unix");
                emitter.emit("node", stream);
                stream.resume();
                child.master.write("sibling", "ascii", masterChildConnection[1]);
            });
        })(child);
        child.addListener("exit", function(){
            // remove the dead one
            delete children[i];
            //children.splice(i, 1);
            // make a new process to replace the dead one
            if(options.restartChildren !== false){
                createChild(tid ++);
            }
        });
    }
    for(var i = 0; i < numChildren; i++){
        createChild(tid ++);
    }
    ["SIGINT", "SIGTERM", "SIGKILL", "SIGQUIT", "SIGHUP", "exit"].forEach(function(signal){
        process.addListener(signal, function(){
            for (var ichild in children){
                try{
                    child = children[ichild];
                    child.kill();
                }catch(e){

                }
            }
            // we use SIGHUP to restart the children
            if(signal !== 'exit' && signal !== 'SIGHUP'){
                options.restartChildren = false;
                process.exit();
            }
        });
    });

@kriszyp kriszyp closed this in 50b0c38 Oct 14, 2011

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