Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 52 additions & 95 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,118 +1,86 @@
var _ = require('lodash');
var util = require('util');
var cluster = require('cluster');
var mixdownMaster = require('./lib/master.js');
var mixdownWorker = require('./lib/worker.js');
var path = require('path');
var packageJSON = require(path.join(process.cwd(), '/package.json'));
var Worker = require('./lib/worker.js');

// Export the factory
module.exports.create = function(mixdown, options) {
var main = new Main(mixdown, options);
return main;
module.exports.create = function (mixdown, options) {
return new Main(mixdown, options);
};

var Main = function(mixdown, options) {
// instance attrs
this.server = null;
this.workers = {}; // if this is a master, then we'll load this with child processes.
this.socket = null;
var Main = function (mixdownConfig, serverOptions) {
this.mixdown = mixdownConfig;

this.master = null; // if this is a master, then we'll set this delegate.
this.worker = null; // if this is a worker, then we'll set this delegate.

// passed configs.
this.mixdown = mixdown;

this.options = _.defaults(options || {}, {
this.options = _.defaults(serverOptions || {}, {
cluster: {
on: false
}
});
};

var logServerInfo = function(server,message) {
var hmap = _.map(server.mixdown.apps, function(app){
return _.pick(app, 'vhosts', 'id');
var logServerInfo = function (server, message) {
var hmap = _.map(server.mixdown.apps, function (app) {
return _.pick(app, 'vhosts', 'id');
});

var address = server.server && server.server.address();
logger.info(message || 'Server Information. ', address|| ' ', hmap);
logger.info(message || 'Server Information. ', address || ' ', hmap);
};

Main.prototype.createMaster = function(callback) {
Main.prototype.createMaster = function (callback) {
var self = this;

// start server. Sets up server, port, and starts the app.
self.master = new mixdownMaster(self.workers, self.options, self.mixdown);
if (!self.options.cluster.on) {
logger.info('Starting master server pid: ' + process.pid);
var master = new Worker(self.mixdown, self.options);
}

self.master.start(function(err, data) {
if (err) {
logger.error("Could not start server. Stopping process.", err);
process.exit();
}
else {
self.socket = data.socket;
self.server = data.server;
logServerInfo(self, 'Server started successfully.');
typeof(callback) === 'function' ? callback(err, self) : null;
}
});
logServerInfo(self, 'Server started successfully.');

if (_.isFunction(callback)) callback(null);
};

Main.prototype.stop = function(callback) {
Main.prototype.stop = function () {
throw new Error('stop() not implemented on server. TODO.');
};

Main.prototype.start = function(callback) {
Main.prototype.start = function (callback) {
var self = this;
var mixdown = this.mixdown;
var options = this.options;

// this reload listener just logs the reload info.
mixdown.on('reload', function() {
mixdown.on('reload', function () {
logServerInfo(self, 'Mixdown reloaded. ');
});

// Start cluster.
var clusterConfig = mixdown.main.options.cluster || {};

if(clusterConfig.on){
var numChidrenToSpawn = clusterConfig.workers || require('os').cpus().length;
if (options.cluster.on) {
// Start cluster.
var numChildrenToSpawn = options.cluster.workers || require('os').cpus().length;

if(cluster.isMaster){
logger.info("Using cluster");
//cluser is on, and this is the master!
logger.info("Starting master with " + numChidrenToSpawn + " workers");
if (cluster.isMaster) {
logger.info("Using cluster.");
//cluster is on, and this is the master!
logger.info("Starting master with " + numChildrenToSpawn + " workers.");

// spawn n workers
for (var i = 0; i < numChidrenToSpawn; i++) {
(function(){
var child = cluster.fork();

child.once('message',function(message){
if(message == 'ready'){

self.workers[child.process.pid] = child;
logger.debug('initial child ready');
}
});

})();
for (var i = 0; i < numChildrenToSpawn; i++) {
var child = cluster.fork();
logger.debug('Initializing worker pid: ' + child.process.pid);
}

// Add application kill signals.
var signals = ['SIGINT', 'SIGTERM', 'SIGQUIT'];
_.each(signals, function(sig) {
_.each(signals, function (sig) {

process.on(sig, function() {
process.on(sig, function () {

_.each(cluster.workers, function(child) {
_.each(cluster.workers, function (child) {
child.destroy(); // send suicide signal
});

// create function to check self all workers are dead.
var checkExit = function() {
if (_.keys(cluster.workers).length == 0) {
var checkExit = function () {
if (_.keys(cluster.workers).length === 0) {
process.exit();
}
else {
Expand All @@ -125,48 +93,37 @@ Main.prototype.start = function(callback) {
});
});

cluster.on('disconnect',function(worker) {
delete self.workers[worker.process.pid];
logger.info('worker '+worker.process.pid+' disconnected');
cluster.on('disconnect', function (worker) {
logger.info('Worker ' + worker.process.pid + ' disconnected.');
});

cluster.on('exit', function(worker) {

// remove the child from the tracked running list..
delete self.workers[worker.process.pid];
cluster.on('exit', function (worker) {

// if it purposely destroyed itself, then do no re-spawn.
if(!worker.suicide){
logger.error('Worker exited unexpectedly. Spawning new worker');
// spawn new child
if (!worker.suicide) {
logger.error('Worker exited unexpectedly. Spawning new worker');
var child = cluster.fork();

child.on('message',function(message){
if(message == 'ready'){
logger.debug('respawned child ready id: ' + child.process.pid);
self.workers[child.process.pid] = child;
}
});
logger.debug('Restarting child with pid: ' + child.process.pid + '...');
}
});

self.createMaster(callback);

}
else {
//cluser is on, and this is a worker!
logger.info("new worker Worker id: "+process.pid);
}
else if (cluster.isWorker) {
//cluster is on, and this is a worker.
logger.info("I'm a new worker Worker pid: " + process.pid);

try {
self.worker = new mixdownWorker(mixdown);
var worker = new Worker(mixdown, options);
}
catch(e) {
typeof(callback) === 'function' ? callback(e, self) : null;
catch (e) {
if (_.isFunction(callback)) callback(e, self);
}
}
}
else {
//cluster isn't running so create a master server.
else if (!options.cluster.on) {
logger.info("Standalone (non-clustered) server.");
self.createMaster(callback);
}
};
Expand Down
102 changes: 0 additions & 102 deletions lib/master.js

This file was deleted.

Loading