Skip to content

Commit

Permalink
[refactor] Use the nssocket defined protocol for stopping and restart…
Browse files Browse the repository at this point in the history
…ing worker processes
  • Loading branch information
indexzero committed Jan 5, 2012
1 parent dc0b457 commit bde27e0
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 144 deletions.
221 changes: 82 additions & 139 deletions lib/forever.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ function getAllProcesses(callback) {
}

socket.dataOnce(['data'], function (data) {
data.socket = fullPath;
next(null, data);
socket.end();
});
Expand Down Expand Up @@ -146,6 +147,59 @@ function getAllPids(processes) {
});
}

function stopOrRestart(action, event, format, target) {
var emitter = new events.EventEmitter(),
results = [],
pids;

function sendAction(proc, next) {
var socket = new nssocket.NsSocket();

socket.connect(proc.socket, function (err) {
if (err) {
next(err);
}

socket.dataOnce([action, 'ok'], function (data) {
next();
socket.end();
});

socket.send([action]);
});

socket.on('error', function (err) {
next(err);
});
}

getAllProcesses(function (processes) {
var procs = processes;

if (target) {
procs = forever.findByIndex(target, processes)
|| forever.findByScript(target, processes);
}

if (procs && procs.length > 0) {
async.map(procs, sendAction, function (err, results) {
if (err) {
emitter.emit('error', err);
}

emitter.emit(event, forever.format(format, procs));
});
}
else {
process.nextTick(function () {
emitter.emit('error', new Error('Cannot find forever process: ' + target));
});
}
});

return emitter;
}

//
// ### function load (options, [callback])
// #### @options {Object} Options to load into the forever module
Expand Down Expand Up @@ -383,33 +437,7 @@ forever.startServer = function () {
// in the list of all processes
//
forever.stop = function (target, format) {
var emitter = new events.EventEmitter(),
results = [],
pids;

getAllProcesses(function (processes) {
var procs = forever.findByIndex(target, processes)
|| forever.findByScript(target, processes);

if (procs && procs.length > 0) {
pids = procs.reduce(function (agg, proc) {
return agg.concat(proc.foreverPid, proc.pid);
}, []);

async.forEach(pids, function (pid, next) {
forever.kill(pid, true, next);
}, function () {
emitter.emit('stop', forever.format(format, procs));
});
}
else {
process.nextTick(function () {
emitter.emit('error', new Error('Cannot find forever process: ' + target));
});
}
});

return emitter;
return stopOrRestart('stop', 'stop', format, target);
};

//
Expand All @@ -420,88 +448,7 @@ forever.stop = function (target, format) {
// in the list of all processes
//
forever.restart = function (target, format) {
var emitter = new events.EventEmitter(),
runner = forever.stop(target, false);

runner.on('stop', function (procs) {
if (procs && procs.length > 0) {
async.forEach(procs, function (proc, next) {
//
// We need to spawn a new process running the forever CLI
// here because we want each process to daemonize separately
// without the main process running `forever restart myscript.js`
// daemonizing itself.
//
var restartCommand = [
'forever',
'start',
'--sourceDir', proc.sourceDir,
'-l', proc.logFile,
'--append true'
];

if (proc.silent) {
restartCommand.push('--silent true');
}

if (proc.command) {
restartCommand.push('-c', command);
}

if (proc.outFile) {
restartCommand.push('-o', path.join(proc.sourceDir, proc.outFile));
}

if (proc.errFile) {
restartCommand.push('-e', path.join(proc.sourceDir, proc.outFile));
}

restartCommand.push(proc.file, proc.options.join(' '));
forever.log.silly('Restarting with options', { options: restartCommand.join(' ') });

exec(restartCommand.join(' '), proc.spawnWith, function (err, stdout, stderr) {
next();
});
}, function () {
emitter.emit('restart', forever.format(format, procs));
});
}
else {
emitter.emit('error', new Error('Cannot find forever process: ' + target));
}
});

// Bubble up the error to the appropriate EventEmitter instance.
runner.on('error', function (err) {
emitter.emit('error', err);
});

return emitter;
};

//
// ### function findByIndex (index, processes)
// #### @index {string} Index of the process to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified index.
//
forever.findByIndex = function (index, processes) {
var proc = processes && processes[parseInt(index, 10)];
return proc ? [proc] : null;
};

//
// ### function findByScript (script, processes)
// #### @script {string} The name of the script to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified script name.
//
forever.findByScript = function (script, processes) {
return !processes
? null
: processes.filter(function (p) {
return p.file === script;
});
return stopOrRestart('restart', 'restart', format, target);
};

//
Expand All @@ -510,36 +457,7 @@ forever.findByScript = function (script, processes) {
// Stops all processes managed by forever.
//
forever.stopAll = function (format) {
var emitter = new events.EventEmitter();

getAllProcesses(function (processes) {
var pids = getAllPids(processes);

if (format) {
processes = forever.format(format, processes);
}

if (pids && processes) {
pids = pids.reduce(function (agg, proc) {
return agg.concat(proc.foreverPid, proc.pid);
}, []);

async.forEach(pids, function (pid, next) {
if (pid !== process.pid) {
forever.kill(pid, true, next);
}
}, function () {
emitter.emit('stopAll', processes);
});
}
else {
process.nextTick(function () {
emitter.emit('stopAll', null);
});
}
});

return emitter;
return stopOrRestart('stop', 'stopAll', format);
};

//
Expand Down Expand Up @@ -603,6 +521,31 @@ forever.tail = function (target, length, callback) {
});
};

//
// ### function findByIndex (index, processes)
// #### @index {string} Index of the process to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified index.
//
forever.findByIndex = function (index, processes) {
var proc = processes && processes[parseInt(index, 10)];
return proc ? [proc] : null;
};

//
// ### function findByScript (script, processes)
// #### @script {string} The name of the script to find.
// #### @processes {Array} Set of processes to find in.
// Finds the process with the specified script name.
//
forever.findByScript = function (script, processes) {
return !processes
? null
: processes.filter(function (p) {
return p.file === script;
});
};

//
// ### function format (format, procs)
// #### @format {Boolean} Value indicating if processes should be formatted
Expand Down
18 changes: 13 additions & 5 deletions lib/forever/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,21 @@ Worker.prototype.start = function (callback) {
});
});

socket.data(['kill'], function () {
self.monitor.on('stop', function () {
socket.send(['kill', 'stop']);
this.exitOnKill && process.exit();
socket.data(['stop'], function () {
self.monitor.once('stop', function () {
socket.send(['stop', 'ok']);
process.exit();
});

self.monitor.kill();
self.monitor.stop();
});

socket.data(['restart'], function () {
self.monitor.once('restart', function () {
socket.send(['restart', 'ok']);
});

self.monitor.restart();
});
});

Expand Down

0 comments on commit bde27e0

Please sign in to comment.