Skip to content

Commit

Permalink
[fix api bin test] Check for scripts with fs.stat() before running th…
Browse files Browse the repository at this point in the history
…em. Use process.kill instead of exec('kill'). Clean logs from command line. Display log file in forever list. Emit save event.
  • Loading branch information
indexzero committed Dec 23, 2010
1 parent 57273ea commit 124cc25
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 31 deletions.
9 changes: 8 additions & 1 deletion bin/forever
Expand Up @@ -107,7 +107,14 @@ loader.on('load', function () {
options.uid = uid;
options.pidFile = 'forever' + uid + '.pid';
options.logFile = argv.l || 'forever' + uid + '.log'
forever.startDaemon(file, options);

fs.stat(file, function (err, stats) {
if (err) {
sys.puts('Cannot start forever: ' + file + ' does not exist.');
process.exit(0);
}
forever.startDaemon(file, options);
});
break;

case 'stop':
Expand Down
94 changes: 65 additions & 29 deletions lib/forever.js
Expand Up @@ -18,15 +18,15 @@ var sys = require('sys'),
var forever = exports, config;

//
// function load ()
// function load (options, [callback])
// Initializes configuration for forever module
//
forever.load = function (options, callback) {
var emitter = new events.EventEmitter();
options = options || {};
options = options || {};
options.root = options.root || path.join('/tmp', 'forever'),
options.pidPath = options.pidPath || path.join(options.root, 'pids');
config = options;
config = options;

// Create the two directories, ignoring errors
fs.mkdir(config.root, 0755, function (err) {
Expand Down Expand Up @@ -95,12 +95,11 @@ forever.stop = function (index, format) {
proc = processes && processes[index];

if (proc) {
exec('kill ' + proc.foreverPid, function () {
exec('kill ' + proc.pid, function () {
if (format) proc = formatProcess(proc, index, '');
emitter.emit('stop', proc);
});
});
process.kill(proc.foreverPid);
process.kill(proc.pid);

if (format) proc = formatProcess(proc, index, '');
emitter.emit('stop', proc);
}
else {
process.nextTick(function () {
Expand All @@ -126,13 +125,15 @@ forever.stopAll = function (format) {
}

if (pids && processes) {
var fPids = pids.map(function (pid) { return pid.foreverPid }).join(' '),
cPids = pids.map(function (pid) { return pid.pid }).join(' ');

exec('kill ' + fPids, function () {
exec('kill ' + cPids, function () {
emitter.emit('stopAll', processes);
});
var fPids = pids.map(function (pid) { return pid.foreverPid }),
cPids = pids.map(function (pid) { return pid.pid });

fPids.concat(cPids).forEach(function (pid) {
process.kill(pid);
});

process.nextTick(function () {
emitter.emit('stopAll', processes);
});
}
else {
Expand Down Expand Up @@ -177,7 +178,7 @@ forever.list = function (format, procs) {
// Utility function for removing excess pid and
// config files used by forever.
//
forever.cleanUp = function () {
forever.cleanUp = function (cleanLogs) {
var emitter = new events.EventEmitter(),
processes = getAllProcesses();

Expand All @@ -196,6 +197,10 @@ forever.cleanUp = function () {
fs.unlink(path.join(config.pidPath, proc.foreverPid + '.fvr'), function () {
// Ignore errors
});

if (cleanLogs) {
fs.unlink(proc.logFile, function () { /* Ignore Errors */ });
}
}

checked++;
Expand Down Expand Up @@ -261,7 +266,8 @@ function formatProcess (proc, index, padding) {
// Create an array of the output we can later join
return [' [' + index + ']', proc.file.green]
.concat(proc.options.map(function (opt) { return opt.green }))
.concat([padding + '[', proc.pid + ',', proc.foreverPid, ']'])
.concat([padding + '[' + proc.pid + ',', proc.foreverPid + ']'])
.concat(proc.logFile.magenta)
.join(' ');
};

Expand All @@ -273,9 +279,7 @@ function getAllProcesses () {
var processes = [];
try {
var files = fs.readdirSync(config.pidPath);
if (files.length === 0) {
return null;
}
if (files.length === 0) return null;

files = files.filter(function(file) { return /\.fvr$/.test(file) });
files.forEach(function (file) {
Expand Down Expand Up @@ -322,6 +326,9 @@ var Forever = function (file, options) {
options.silent = options.silent || false;
options.forever = options.forever || false;
options.command = options.command || 'node';
options.options = options.options || [];

this.childExists = false;

if (Array.isArray(file)) {
options.command = file[0];
Expand Down Expand Up @@ -361,7 +368,14 @@ Forever.prototype.start = function (restart) {
});
}

var child = spawn(this.options.command, this.options.options);
var child = this.trySpawn();
if (!child) {
process.nextTick(function () {
self.emit('error', new Error('Target script does not exist: ' + self.options.options[0]));
});
return this;
}

this.child = child;
this.running = true;

Expand Down Expand Up @@ -418,6 +432,28 @@ Forever.prototype.start = function (restart) {
return this;
};

//
// function trySpawn()
// Tries to spawn the target Forever child process. Depending on
// configuration, it checks the first argument of the options
// to see if the file exists. This is useful is you are
// trying to execute a script with an env: e.g. node myfile.js
//
Forever.prototype.trySpawn = function () {
if (this.options.command === 'node' || (this.options.checkFile
&& !this.childExists)) {
try {
var stats = fs.statSync(this.options.options[0]);
this.childExists = true;
}
catch (ex) {
return false;
}
}

return spawn(this.options.command, this.options.options);
};

//
// function save ()
// Persists this instance of forever to disk.
Expand Down Expand Up @@ -446,6 +482,7 @@ Forever.prototype.save = function () {
var childPath = path.join(config.pidPath, childData.foreverPid + '.fvr');
fs.writeFile(childPath, JSON.stringify(childData), function (err) {
if (err) self.emit('error', err);
self.emit('save', childPath, childData);
});

//
Expand All @@ -460,13 +497,12 @@ Forever.prototype.save = function () {
// process.exit(0);
// });
//
//process.on('SIGTERM', function () {
// process.exit(0);
//});

//process.on('exit', function () {
// fs.unlinkSync(childPath);
//});
// process.on('SIGTERM', function () {
// process.exit(0);
// });
// process.on('exit', function () {
// fs.unlinkSync(childPath);
// });

return this;
};
Expand Down
15 changes: 14 additions & 1 deletion test/forever-test.js
Expand Up @@ -43,7 +43,7 @@ vows.describe('forever').addBatch({
}
}
},
"when running error-on-timer sample three times": {
"running error-on-timer sample three times": {
topic: function () {
var child = new (forever.Forever)(path.join(__dirname, '..', 'samples', 'error-on-timer.js'), {
max: 3,
Expand Down Expand Up @@ -71,5 +71,18 @@ vows.describe('forever').addBatch({
"should get back moo": function (err, buf) {
assert.equal(buf.toString(), 'moo\n');
}
},
"attempting to start a script that doesn't exist": {
topic: function () {
var child = forever.start('invalid-path.js', {
max: 1,
silent: true
});
child.on('error', this.callback.bind({}, null));
},
"should throw an error about the invalid file": function (err) {
assert.isNotNull(err);
assert.isTrue(err.message.indexOf('does not exist') !== -1);
}
}
}).export(module);

0 comments on commit 124cc25

Please sign in to comment.