Skip to content

Commit

Permalink
[api test bin doc] Added stop by script name feature. Improved the cl…
Browse files Browse the repository at this point in the history
…eanlogs functionality. Made event emission consistent. Added to docs
  • Loading branch information
indexzero committed Dec 24, 2010
1 parent b7f792b commit 14c7aa8
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 44 deletions.
25 changes: 18 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ There are two distinct ways to use forever: through the command line interface,
You can use forever to run any kind of script continuously (whether it is written in node.js or not). The usage options are simple:

<pre>
usage: forever [start | stop | stopall | list] [options] SCRIPT [script options]
usage: forever [start | stop | stopall | list | cleanlogs] [options] SCRIPT [script options]

options:
start start SCRIPT as a daemon
stop stop the daemon SCRIPT
stopall stop all running forever scripts
list list all running forever scripts
cleanlogs [CAREFUL] Deletes all historical forever log files

-m MAX Only run the specified script MAX times
-l LOGFILE Logs the forever output to LOGFILE
Expand Down Expand Up @@ -105,10 +106,11 @@ Each forever object is an instance of the node.js core EventEmitter. There are s

* error [err]: Raised when an error occurs
* stop [process]: Raised when the target script is stopped by the user
* restart [err, forever]: Raised each time the target script is restarted
* exit [err, forever]: Raised when the call to forever.run() completes
* stdout [err, data]: Raised when data is received from the child process' stdout
* stderr [err, data]: Raised when data is received from the child process' stderr
* save [path, data]: Raised when the target Forever object persists the pid information to disk.
* restart [forever]: Raised each time the target script is restarted
* exit [forever]: Raised when the call to forever.run() completes
* stdout [data]: Raised when data is received from the child process' stdout
* stderr [data]: Raised when data is received from the child process' stderr

## Using forever module from node.js
In addition to using a Forever object, the forever module also exposes some useful methods. Each method returns an instance of an EventEmitter which emits when complete. See the [forever binary script][1] for sample usage.
Expand All @@ -119,6 +121,12 @@ Sets the specified configuration (config) for the forever module. In addition to
* root: Directory to put all default forever log files
* pidPath: Directory to put all forever *.pid files

### forever.start (file, options)
Starts a script with forever.

### forever.startDaemon (file, options)
Starts a script with forever as a daemon. WARNING: Will daemonize the current process.

### forever.stop (index)
Stops the forever daemon script at the specified index. These indices are the same as those returned by forever.list(). This method returns an EventEmitter that raises the 'stop' event when complete.

Expand All @@ -131,14 +139,17 @@ Returns a list of metadata objects about each process that is being run using fo
### forever.cleanup ()
Cleans up any extraneous forever *.pid or *.fvr files that are on the target system. This method returns an EventEmitter that raises the 'cleanUp' event when complete.

### forever.cleanLogsSync
Removes all log files from the root forever directory that do not belong to current running forever processes.

## Run Tests
The test coverage for 0.3.0 is currently lacking, but will be improved in 0.3.1.
The test coverage for 0.3.1 is currently lacking, but will be improved in 0.3.2.
<pre>
vows test/*-test.js --spec
</pre>

#### Author: [Charlie Robbins](http://www.charlierobbins.com)
#### Contributors: [Fedor Indutny](http://github.com/donnerjack13589)
#### Contributors: [Fedor Indutny](http://github.com/donnerjack13589), [James Halliday](http://substack.net/)

[0]: http://nodejitsu.com
[1]: https://github.com/indexzero/forever/blob/master/bin/forever
8 changes: 1 addition & 7 deletions bin/forever
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ var loader = forever.load(config);
loader.on('load', function () {
var tidy = forever.cleanUp(action === 'cleanlogs');
tidy.on('cleanUp', function () {
// Run all of the files forever
if (action) {
switch (action) {
case 'start':
Expand All @@ -126,12 +125,7 @@ loader.on('load', function () {
break;

case 'stop':
if (!(/(\d+)/.test(file))) {
sys.puts(file + ' is not a valid index for a forever process.');
process.exit(0);
}

var runner = forever.stop(parseInt(file), true);
var runner = forever.stop(file, true);
runner.on('stop', function (process) {
sys.puts('Forever stopped process:');
sys.puts(process);
Expand Down
83 changes: 54 additions & 29 deletions lib/forever.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

var sys = require('sys'),
fs = require('fs'),
eyes = require('eyes'),
colors = require('colors'),
path = require('path'),
events = require('events'),
Expand All @@ -17,6 +18,8 @@ var sys = require('sys'),

var forever = exports, config;

forever.version = [0, 3, 1];

//
// function load (options, [callback])
// Initializes configuration for forever module
Expand Down Expand Up @@ -85,31 +88,53 @@ forever.startDaemon = function (file, options) {
};

//
// function stop (index)
// Stops the process with the specified
// index in the list of all processes
// function stop (target, [format])
// Stops the process with the specified index or
// script name in the list of all processes
//
forever.stop = function (index, format) {
forever.stop = function (target, format) {
var emitter = new events.EventEmitter(),
processes = getAllProcesses(),
proc = processes && processes[index];
results = [];

if (proc) {
process.kill(proc.foreverPid);
process.kill(proc.pid);

if (format) proc = formatProcess(proc, index, '');
emitter.emit('stop', proc);
var procs = /(\d+)/.test(target) ? forever.findByIndex(target, processes)
: forever.findByScript(target, processes);

if (procs && procs.length > 0) {
procs.forEach(function (proc) {
process.kill(proc.foreverPid);
process.kill(proc.pid);
});

process.nextTick(function () {
emitter.emit('stop', format ? forever.list(true, procs) : procs);
});
}
else {
process.nextTick(function () {
emitter.emit('error', new Error('Cannot find forever process with index: ' + index));
emitter.emit('error', new Error('Cannot find forever process: ' + target));
});
}

return emitter;
};

//
// function findByIndex (index, processes)
// Finds the process with the specified index.
//
forever.findByIndex = function (index, processes) {
return processes && [processes[parseInt(index)]];
};

//
// function findByScript (script, processes)
// Finds the process with the specified script name.
//
forever.findByScript = function (script, processes) {
return processes.filter(function (p) { return p.file === script });
};

//
// function stopAll (format)
// Stops all forever processes
Expand All @@ -119,7 +144,7 @@ forever.stopAll = function (format) {
var emitter = new events.EventEmitter(),
processes = getAllProcesses() || [],
pids = getAllPids(processes);

if (format) {
processes = forever.list(format, processes);
}
Expand Down Expand Up @@ -182,7 +207,7 @@ forever.cleanUp = function (cleanLogs) {
var emitter = new events.EventEmitter(),
processes = getAllProcesses(true);

if (cleanLogs) forever.cleanLogsSync();
if (cleanLogs) forever.cleanLogsSync(processes);

if (processes && processes.length > 0) {
var checked = 0;
Expand Down Expand Up @@ -223,14 +248,19 @@ forever.cleanUp = function (cleanLogs) {
};

//
// function cleanLogsSync ()
// Removes all log files from the
// root forever directory
// function cleanLogsSync (processes)
// Removes all log files from the root forever directory
// that do not belong to current running forever processes.
// [processes]: The set of all forever processes
//
forever.cleanLogsSync = function () {
var files = fs.readdirSync(config.root);
forever.cleanLogsSync = function (processes) {
var files = fs.readdirSync(config.root),
runningLogs = processes && processes.map(function (p) { return p.logFile.split('/').pop() });

files.forEach(function (file) {
if (/\.log$/.test(file)) fs.unlinkSync(path.join(config.root, file));
if (/\.log$/.test(file) && (!runningLogs || runningLogs.indexOf(file) === -1)) {
fs.unlinkSync(path.join(config.root, file));
}
});
};

Expand Down Expand Up @@ -441,7 +471,7 @@ Forever.prototype.start = function (restart) {
self.times++;

if (self.forever || self.times < self.max) {
self.emit('restart', null, self);
self.emit('restart', self);
process.nextTick(function () {
self.log('Forever restarting script for ' + self.times + ' time');
self.start(true).save();
Expand All @@ -451,16 +481,11 @@ Forever.prototype.start = function (restart) {
this.running = false;

// If had to write to an stdout file, close it
if (self.stdout) {
self.stdout.end();
}

if (self.stdout) self.stdout.end();
// If had to write to an stderr file, close it
if (self.stderr) {
self.stderr.end();
}
if (self.stderr) self.stderr.end();

self.emit('exit', null, self);
self.emit('exit', self);
}
});

Expand Down
2 changes: 1 addition & 1 deletion test/forever-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ vows.describe('forever').addBatch({
options: []
});

child.on('exit', this.callback);
child.on('exit', this.callback.bind({}, null));
child.start();
},
"should emit 'exit' when completed": function (err, child) {
Expand Down

0 comments on commit 14c7aa8

Please sign in to comment.