Skip to content

Commit

Permalink
Merge pull request #1184 from Unitech/development
Browse files Browse the repository at this point in the history
v0.12.11 release
  • Loading branch information
jshkurti committed Apr 17, 2015
2 parents 1d1d9fa + 2ddee3e commit 382c52d
Show file tree
Hide file tree
Showing 51 changed files with 1,039 additions and 200 deletions.
20 changes: 17 additions & 3 deletions ADVANCED_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ $ pm2 updatePM2 # Update in memory pm2
$ pm2 ping # Ensure pm2 daemon has been launched
$ pm2 sendSignal SIGUSR2 my-app # Send system signal to script
$ pm2 start app.js --no-daemon
$ pm2 start app.js --no-vizion
$ pm2 start app.js --no-autorestart
```

## Different ways to launch a process
Expand Down Expand Up @@ -227,6 +229,8 @@ Options:
--ignore-watch <folders|files> folder/files to be ignored watching, chould be a specific name or regex - e.g. --ignore-watch="test node_modules "some scripts""
--node-args <node_args> space delimited arguments to pass to node in cluster mode - e.g. --node-args="--debug=7001 --trace-deprecation"
--no-color skip colors
--no-vizion skip vizion features (versioning control)
--no-autorestart do not automatically restart apps
```


Expand Down Expand Up @@ -319,8 +323,8 @@ JSON:

Units can be K(ilobyte), M(egabyte), G(igabyte).

>
Actually the way it works when you type :

Actually the way it works when you type:
`pm2 start app.js --max-memory-restart 50M`
commander module will transform it to `maxMemoryRestart: "50M"`, then after being processed by PM2 logic it will become an env variable as follows `max_memory_restart : 52428800 // in bytes this time`.
But since programmatic interface doesn't use commander you have to give it raw-mode : `maxMemoryRestart`.
Expand Down Expand Up @@ -380,6 +384,12 @@ You can also reload all logs via the command line with:
$ pm2 reloadLogs
```

### Manually triggering garbage collection for PM2

```bash
$ pm2 gc
```

### Options

```bash
Expand Down Expand Up @@ -638,6 +648,8 @@ You can define parameters for your apps in `processes.json`:
"log_date_format" : "YYYY-MM-DD HH:mm Z",
"ignore_watch" : ["[\\/\\\\]\\./", "node_modules"],
"watch" : true,
"vizion" : true,
"autorestart" : true,
"node_args" : "--harmony",
"cwd" : "/this/is/a/path/to/start/script",
"env": {
Expand Down Expand Up @@ -718,6 +730,8 @@ Note that if you execute `pm2 start node-app-2` again, it will spawn an addition
"merge_logs" : true,
"exec_interpreter" : "node",
"exec_mode" : "fork",
"autorestart" : false, // enable/disable automatic restart when an app crashes or exits
"vizion" : false, // enable/disable vizion features (versioning control)
"env": {
"NODE_ENV": "production",
"AWESOME_SERVICE_API_TOKEN": "xxx"
Expand Down Expand Up @@ -1154,7 +1168,7 @@ pm2.connect(function(err) {
</tr>
<tr>
<td><b>Start</b></td>
<td>pm2.start(script_path|json_path, options, fn(err, proc){})</td>
<td>pm2.start(script_path|json_object|json_path, options, fn(err, proc){})</td>
</tr>
<tr>
<td>Options </td>
Expand Down
34 changes: 31 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,41 @@
# Coming Next

- `--no-logs` flag : doesn't save any logs (some people use their own logging system)
- `--no-vizion` flag : starts an app completely without vizion features
- `--no-restart` flag : starts PM2 without automatic restart feature
- dump/resurrect will leave 'stopped' apps as stopped instead of restarting every app
- YAML support for apps declarations
- Improve app declaration file parsing (log_file, out_file, error_file)

# 0.12.10 (Current Stable)
# 0.12.11 (Current stable)

- `--no-autorestart` flag : starts an app without automatic restart feature
(`"autorestart" : false` in JSON declaration)

- `--no-vizion` flag : starts an app completely without vizion features
(`"vizion" : false` in JSON declaration)

- Fix #1146 : add module._initPaths() on ProcessContainer.js so it forces each
new process to take the current NODE_PATH env value in account

- New: pm2.start() now handles json objects as param

- Added: timestamps to KM agent logs

- Fix: now properly closes all fds after logging has finished.

- New command: pm2 gc (manually triggers garbage collection for PM2)

- VersioningManagment: exec() timeout configurable via .json

- Fix #1143 :
If we start let's say 4 instances of an app (cluster_mode),
Each app will have a value in process.env.NODE_APP_INSTANCE which will be 0 for the first one,
1, 2 and 3 for the next ones.

- Fix #1154 :
Negative arguments to '-i' are substracted to CPU cores number.
E.g: 'pm2 start app.js -i -3' in a 8 cpus environment will start 5 instances (8 - 3).

# 0.12.10

- Fix : PM2 interactor doesn't send data about dead processes ('_old_') anymore.
- Fix #1137 : Safe params for 'pm2 list' so cli-table won't fail
Expand Down
20 changes: 16 additions & 4 deletions bin/pm2
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ commander.version(pkg.version)
.option('--ignore-watch <folders|files>', 'folder/files to be ignored watching, chould be a specific name or regex - e.g. --ignore-watch="test node_modules \"some scripts\""')
.option('--node-args <node_args>', 'space delimited arguments to pass to node in cluster mode - e.g. --node-args="--debug=7001 --trace-deprecation"')
.option('--no-color', 'skip colors')
.option('--no-vizion', 'start an app without vizion feature (versioning control)')
.option('--no-autorestart', 'start an app without automatic restart')

.usage('[cmd] app');

commander.on('--help', function() {
console.log(' Basic Examples:');
console.log('');
console.log(' Start an app using all CPUs available + set a name :');
console.log(' $ pm2 start app.js -i max --name "api"');
console.log(' $ pm2 start app.js -i 0 --name "api"');
console.log('');
console.log(' Restart the previous app launched, by name :');
console.log(' $ pm2 restart api');
Expand Down Expand Up @@ -161,10 +164,10 @@ commander.command('start <file|json|stdin>')
process.stdin.pause();
CLI.startJson(cmd, commander, 'pipe');
});
} else if (cmd.slice(-5) == '.json')
CLI.startJson(cmd, commander, 'file');
else
}
else {
CLI.start(cmd, commander);
}
});

commander.command('deploy <file|environment>')
Expand Down Expand Up @@ -594,6 +597,15 @@ commander.command('backward <name>')
CLI.backward(pm2_name);
});

//
// Force PM2 to trigger garbage collection
//
commander.command('gc')
.description('force PM2 to trigger garbage collection')
.action(function() {
CLI.forceGc();
});

//
// Catch all
//
Expand Down
64 changes: 64 additions & 0 deletions doc/DEBUG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

# List open files

```
$ lsof -i -n -P | grep pm2
```

Display limits

```
$ ulimit -a
```

# Memory leak

```
require('webkit-devtools-agent').start({
port: 9999,
bind_to: '0.0.0.0',
ipc_port: 3333,
verbose: true
});
```

# Observe feature

```
///////////////////////////////////////////////////////
// Temporary disabling this because tests don't pass //
///////////////////////////////////////////////////////
var obs = new observe.ObjectObserver(God.clusters_db);
obs.open(function() {
God.dumpProcessList && God.dumpProcessList(function() {
console.log('Process List Dumped');
});
});
if (!Object.observe) {
setInterval(Platform.performMicrotaskCheckpoint, 1000);
}
```

# UncaughtException handling

```
process.on('uncaughtException', function(err) {
if (err && err.message == 'Resource leak detected.') {
// Catch and ignore this error
// Throw by cluster module with Node 0.11.13<=
console.error(err.stack);
console.error('Resource leak detected for cluster module');
}
else if (err) {
console.error(err.stack);
if (God.dumpProcessList)
God.dumpProcessList(function() {
return process.exit(cst.ERROR_EXIT);
});
else
return process.exit(cst.ERROR_EXIT);
}
});
```
5 changes: 4 additions & 1 deletion doc/PULL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ or to the optional specified commit ID.

Everytime a backward/pull/forward command is executed, pm2 checks in ecosystem.json, process.json and package.json (in that order) for commands to run (e.g. npm install).
The field should be named post_update and should be an array of commands.
You can also set the timeout for exec() command with 'exec_timeout' field (in ms).
By default it is 60000 (60sec).
Your file should look something like this :

```json
Expand All @@ -50,7 +52,8 @@ Your file should look something like this :
"script" : "app.js",
"post_update" : ["echo App has been updated, running npm install...",
"npm install",
"echo App is being restarted now"]
"echo App is being restarted now"],
"exec_timeout" : 30000
}
]
}
Expand Down
54 changes: 44 additions & 10 deletions lib/CLI.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,29 @@ CLI.pm2Init = function() {
}
};

/**
* Entry point to start an app / json file
* keep retro-compat for startJson
*/
CLI.start = CLI.startJson = function(cmd, opts, cb) {
if (typeof(opts) == "function") {
cb = opts;
opts = {};
}

if ((typeof(cmd) === 'string' && cmd.indexOf('.json') != -1) || typeof(cmd) === 'object')
CLI._startJson(cmd, opts, 'file', cb);
else
CLI._start(cmd, opts, cb);
};

/**
* Method to start a script
* @method startFile
* @param {string} script script name (will be resolved according to location)
* @return
*/
CLI.start = function(script, opts, cb) {
CLI._start = function(script, opts, cb) {
if (typeof opts == "function") {
cb = opts;
opts = {};
Expand Down Expand Up @@ -319,7 +335,7 @@ CLI.actionFromJson = function(action, file, jsonVia, cb) {
* @param {string} jsonVia
* @param {function} cb
*/
CLI.startJson = function(cmd, opts, jsonVia, cb) {
CLI._startJson = function(cmd, opts, jsonVia, cb) {
var appConf, deployConf = null;

if (typeof(cb) === 'undefined' && typeof(jsonVia) === 'function')
Expand Down Expand Up @@ -382,7 +398,7 @@ CLI.startJson = function(cmd, opts, jsonVia, cb) {
next();
});
}, function(err) {
return cb ? cb(err, appConf) : speedList();
return cb ? cb(err || null, appConf) : speedList();
});
};

Expand Down Expand Up @@ -760,7 +776,7 @@ CLI._reloadProcessName = function(process_name, reload_method, cb) {

Satan.notifyGod('restart', proc.pm2_env.pm_id);

return CLI._restart(process_name, next);
return CLI.restart(process_name, next);
}

Satan.executeRemote(reload_method, proc.pm2_env.pm_id, function(err, res) {
Expand Down Expand Up @@ -1231,7 +1247,7 @@ CLI.describe = function(pm2_id, cb) {
});

if (found_proc.length === 0) {
printError('%s doesn\'t exist', pm2_id);
printError(cst.PREFIX_MSG_WARNING + '%s doesn\'t exist', pm2_id);
return cb ? cb(null, []) : exitCli(cst.ERROR_EXIT);
}

Expand Down Expand Up @@ -1638,7 +1654,7 @@ var Version = require('./tools/VersionManagement.js');
* @return
*/
CLI.pullAndRestart = function (process_name, cb) {
Version._pull({process_name: process_name, action: 'restart'}, cb);
Version._pull({process_name: process_name, action: 'reload'}, cb);
};

/**
Expand Down Expand Up @@ -1687,6 +1703,24 @@ CLI.backward = Version.backward;
*/
CLI.forward = Version.forward;


/**
* CLI method for triggering garbage collection manually
* @method forcegc
* @return
*/
CLI.forceGc = function() {
Satan.executeRemote('forceGc', {}, function(err, data) {
if (data && data.success === false) {
printError(cst.PREFIX_MSG_ERR + 'Garbage collection failed');
exitCli(cst.ERRO_EXIT);
} else {
printOut(cst.PREFIX_MSG + 'Garbage collection manually triggered');
exitCli(cst.SUCCESS_EXIT);
}
});
};

//
// Private methods
//
Expand Down Expand Up @@ -1932,10 +1966,10 @@ function checkDeprecates(conf){
conf.instances = parseInt(conf.instances) || 0;

// Ensure instance param is not a negative value
if (conf.instances < 0) {
warn('You passed a negative value to indicate the number of instances... Setting this to maximum instances.');
conf.instances = 0;
}
// if (conf.instances < 0) {
// warn('You passed a negative value to indicate the number of instances... Setting this to maximum instances.');
// conf.instances = 0;
// }
}

/**
Expand Down
12 changes: 10 additions & 2 deletions lib/Common.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,23 @@ Common.prepareAppConf = function(app, cwd, outputter) {
var formated_app_name = app.name.replace(/[^a-zA-Z0-9\\.\\-]/g, '-');

['log', 'out', 'error', 'pid'].forEach(function(f){

var af = app[f + '_file'], ps, ext = (f == 'pid' ? 'pid':'log'), isStd = !~['log', 'pid'].indexOf(f);
if((f == 'log' && typeof af == 'boolean' && af) || (f != 'log' && !af)){
if ((f == 'log' && typeof af == 'boolean' && af) || (f != 'log' && !af)) {
ps = [cst['DEFAULT_' + ext.toUpperCase() + '_PATH'], formated_app_name + (isStd ? '-' + f : '') + '.' + ext];
}else if(f != 'log' || (f == 'log' && af)){
} else if (f != 'log' || (f == 'log' && af)) {
ps = [cwd, af];

if (!fs.existsSync(path.dirname(af))) {
Common.printError(cst.PREFIX_MSG_ERR + 'Folder does not exists: ' + path.dirname(af));
throw new Error('Folder does not exists');
}

}
// PM2 paths
ps && (app['pm_' + (isStd ? f.substr(0, 3) + '_' : '') + ext + '_path'] = p.resolve.apply(null, ps));
delete app[f + '_file']

});

//set port env variable
Expand Down
Loading

0 comments on commit 382c52d

Please sign in to comment.