spawner.js | |
---|---|
/*
* spawner.js: Spawner object responsible for starting carapace processes.
*
* (C) 2010, Nodejitsu Inc.
*
*/
var fs = require('fs'),
path = require('path'),
forever = require('forever'),
haibu = require('../../haibu');
var Spawner = exports.Spawner = function Spawner(options) {
options = options || {};
this.maxRestart = options.maxRestart;
this.minUptime = options.minUptime;
this.silent = options.silent || false;
this.appsDir = options.appsDir || haibu.config.get('directories:apps');
this.packageDir = options.packageDir || haibu.config.get('directories:packages');
this.host = options.host || '127.0.0.1';
}; | |
function trySpawn (app, callback)@app {App} Application to attempt to spawn on this server.@callback {function} Continuation passed to respond to.Attempts to spawn the application with the package.json manifest represented by @app, then responds to @callback. | Spawner.prototype.trySpawn = function (app, callback) {
var self = this,
repo = app instanceof haibu.repository.Repository ? app : haibu.repository.create(app);
repo.bootstrap(function (err, existed) {
if (err) {
return callback(err);
}
else if (existed) {
return self.spawn(repo, callback);
}
repo.init(function (err, inited) {
if (err) {
return callback(err);
}
self.spawn(repo, callback);
});
});
};
Spawner.prototype.foreverOptions = function foreverOptions (repo, app, options) {
options = options || {};
return
} |
function spawn (app, callback)@app {App} Application to attempt to spawn on this server.@callback {function} Continuation passed to respond to.spawns the appropriate carapace for an Application and bootstraps with the events listed | Spawner.prototype.spawn = function spawn (repo, callback) {
var self = this,
app = repo instanceof haibu.repository.Repository ? repo.app : app,
meta = { app: app.name, user: app.user },
script = repo.startScript,
foreverOptions,
drone;
haibu.emit('spawn:setup', 'info', meta);
foreverOptions = {
silent: true,
cwd: repo.homeDir,
env: app.env,
minUptime: this.minUptime,
command: path.join(__dirname, '..', '..', '..', 'node_modules', '.bin', 'carapace'),
options: []
}; |
Concatenate the | Object.keys(haibu.activePlugins).forEach(function (plugin) {
var spawn;
if (haibu.activePlugins[plugin].argv) {
haibu.emit('plugin:argv', 'info', {
app: app.name,
username: app.user,
plugin: plugin
});
spawn = haibu.activePlugins[plugin].argv(repo);
if (spawn.script) {
script = spawn.script
}
if (spawn.argv) {
foreverOptions.options = foreverOptions.options.concat(spawn.argv);
}
}
});
foreverOptions.forever = typeof self.maxRestart === 'undefined';
if (typeof self.maxRestart !== 'undefined') {
foreverOptions.max = self.maxRestart;
}
|
Before we attempt to spawn, let's check if the startPath actually points to a file Trapping this specific error is useful as the error indicates an incorrect scripts.start property in the package.json | fs.stat(repo.startScript, function (err, stats) {
if (err) {
return callback(new Error('package.json error: ' + 'can\'t find starting script: ' + repo.app.scripts.start));
}
haibu.emit('spawn:start', 'info', {
options: foreverOptions.options.join(' '),
app: meta.app,
user: meta.user
});
drone = new forever.Monitor(script, foreverOptions); |
TODO (indexzero): This output should be in its own Loggly input (i.e. log.user instead of log.drone) | drone.on('stdout', function (data) {
haibu.emit('drone:stdout', 'info', data.toString(), meta);
});
drone.on('stderr', function (data) {
haibu.emit('drone:stderr', 'error', data.toString(), meta);
});
drone.on('error', function (data) { |
Remark: Now that it has exited what should we do? | haibu.emit('drone:err', 'error', data.toString(), meta);
});
haibu.running.hook.once('*::carapace::port', function (info) {
result.socket = {
host: self.host,
port: info.port
};
callback(null, result);
});
drone.once('start', function (monitor, data) {
result = {
monitor: monitor,
process: monitor.child,
drone: data
};
});
drone.on('exit', function () { |
Remark: Now that it has exited what should we do?
This would only happen in the event that it is a | errState = true;
});
drone.start();
});
};
|