mirror of
https://github.com/Unitech/pm2.git
synced 2025-12-08 20:35:53 +00:00
167 lines
4.0 KiB
JavaScript
167 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* @file Fork execution related functions
|
|
* @author Alexandre Strzelewicz <as@unitech.io>
|
|
* @project PM2
|
|
*/
|
|
|
|
var log = require('debug')('pm2:god');
|
|
var fs = require('fs');
|
|
var cst = require('../../constants.js');
|
|
var uidNumber = require('uid-number');
|
|
var moment = require('moment');
|
|
var Common = require('../Common');
|
|
/**
|
|
* Description
|
|
* @method exports
|
|
* @param {} God
|
|
* @return
|
|
*/
|
|
module.exports = function ForkMode(God) {
|
|
/**
|
|
* For all apps - FORK MODE
|
|
* fork the app
|
|
* @method forkMode
|
|
* @param {} pm2_env
|
|
* @param {} cb
|
|
* @return
|
|
*/
|
|
God.forkMode = function forkMode(pm2_env, cb) {
|
|
var command, args;
|
|
|
|
log('Entering in fork mode');
|
|
var spawn = require('child_process').spawn;
|
|
|
|
var interpreter = pm2_env.exec_interpreter || 'node';
|
|
var pidFile = pm2_env.pm_pid_path;
|
|
|
|
if (interpreter !== 'none') {
|
|
command = interpreter;
|
|
args = [pm2_env.pm_exec_path];
|
|
}
|
|
else {
|
|
command = pm2_env.pm_exec_path;
|
|
args = [ ];
|
|
}
|
|
|
|
// Concat args if present
|
|
if (pm2_env.args)
|
|
args = args.concat(eval((pm2_env.args)));
|
|
|
|
var stdout, stderr;
|
|
var outFile = pm2_env.pm_out_log_path;
|
|
var errFile = pm2_env.pm_err_log_path;
|
|
|
|
/**
|
|
* Get the uid and gid number if run_as_user or run_as_group
|
|
* is present
|
|
* @method getuid
|
|
* @param {function} cb A callback that reveice error, uid and gid
|
|
*/
|
|
function getugid(cb) {
|
|
var user = pm2_env.run_as_user || process.getuid();
|
|
var group = pm2_env.run_as_group || process.getgid();
|
|
|
|
uidNumber(user, group, cb);
|
|
}
|
|
|
|
/**
|
|
* Description
|
|
* @method startLogging
|
|
* @param {} cb
|
|
* @return
|
|
*/
|
|
function startLogging(cb) {
|
|
stdout = fs.createWriteStream(outFile, { flags : 'a' });
|
|
|
|
stdout.on('open', function() {
|
|
stderr = fs.createWriteStream(errFile, { flags : 'a' });
|
|
stderr.on('open', function() {
|
|
return cb();
|
|
});
|
|
});
|
|
}
|
|
|
|
startLogging(function() {
|
|
getugid(function(e, uid, gid){
|
|
if(e){
|
|
God.logAndGenerateError(e);
|
|
if (cb) return cb(e);
|
|
}
|
|
|
|
try {
|
|
var cspr = spawn(command, args, {
|
|
env : pm2_env,
|
|
detached : true,
|
|
gid : gid,
|
|
uid : uid,
|
|
cwd : pm2_env.pm_cwd || process.cwd(),
|
|
stdio : ['ipc', null, null]
|
|
});
|
|
} catch(e) {
|
|
God.logAndGenerateError(e);
|
|
if (cb) return cb(e);
|
|
}
|
|
|
|
cspr.process = {};
|
|
cspr.process.pid = cspr.pid;
|
|
cspr.pm2_env = pm2_env;
|
|
cspr.pm2_env.status = cst.ONLINE_STATUS;
|
|
|
|
cspr.stderr.on('data', function forkErrData(data) {
|
|
|
|
var log_data = data.toString();
|
|
if (pm2_env.log_date_format)
|
|
log_data = moment().format(pm2_env.log_date_format) + ': ' + log_data;
|
|
|
|
stderr.write(log_data);
|
|
|
|
God.bus.emit('log:err', {
|
|
process : cspr,
|
|
data : data.toString()
|
|
});
|
|
});
|
|
|
|
cspr.stdout.on('data', function forkOutData(data) {
|
|
|
|
var log_data = data.toString();
|
|
if (pm2_env.log_date_format)
|
|
log_data = moment().format(pm2_env.log_date_format) + ': ' + log_data;
|
|
|
|
stdout.write(log_data);
|
|
|
|
God.bus.emit('log:out', {
|
|
process : cspr,
|
|
data : data.toString()
|
|
});
|
|
});
|
|
|
|
cspr.on('message', function forkMessage(data) {
|
|
God.bus.emit(data.type ? data.type : 'process:msg', {
|
|
process : cspr,
|
|
data : data
|
|
});
|
|
});
|
|
|
|
fs.writeFileSync(pidFile, cspr.pid);
|
|
|
|
cspr.once('close', function forkClose(status) {
|
|
try {
|
|
stderr.close();
|
|
stdout.close();
|
|
} catch(e) { God.logAndGenerateError(e);}
|
|
});
|
|
|
|
cspr._reloadLogs = startLogging;
|
|
|
|
cspr.unref();
|
|
|
|
if (cb) return cb(null, cspr);
|
|
return false;
|
|
});
|
|
});
|
|
|
|
};
|
|
};
|