'use strict'; // TODO if RAM is very low we should not fork at all, // but use a different process altogether console.info('pid:', process.pid); console.info('title:', process.title); console.info('arch:', process.arch); console.info('platform:', process.platform); console.info('\n\n\n[MASTER] Welcome to WALNUT!'); function tryConf(pathname, def) { try { return require(pathname); } catch(e) { return def; } } var path = require('path'); var cluster = require('cluster'); //var minWorkers = 2; var numCores = 2; // Math.max(minWorkers, require('os').cpus().length); var workers = []; var state = { firstRun: true }; // TODO Should these be configurable? If so, where? // TODO communicate config with environment vars? var walnut = tryConf( path.join('..', '..', 'config.walnut') , { externalPort: 443 , externalInsecurePort: 80 } ); var info = { type: 'walnut.init' , conf: { protocol: 'http' , externalPort: walnut.externalPort || 443 , externalPortInsecure: walnut.externalInsecurePort || 80 // TODO externalInsecurePort , localPort: walnut.localPort || 3000 // system / local network , trustProxy: true , varpath: path.join(__dirname, '..', '..', 'var') , etcpath: path.join(__dirname, '..', '..', 'etc') } }; function fork() { if (workers.length < numCores) { workers.push(cluster.fork()); } } cluster.on('online', function (worker) { console.info('[MASTER] Worker ' + worker.process.pid + ' is online'); fork(); if (state.firstRun) { state.firstRun = false; // TODO dyndns in master? } function touchMaster(msg) { if ('walnut.webserver.listening' !== msg.type) { console.warn('[MASTER] received unexpected message from worker'); console.warn(msg); return; } state.workers = workers; // calls init if init has not been called require('../lib/master').touch(info.conf, state).then(function (newConf) { worker.send({ type: 'walnut.webserver.onrequest', conf: newConf }); newConf.addWorker(worker); }); } worker.send(info); worker.on('message', touchMaster); }); cluster.on('exit', function (worker, code, signal) { console.info('[MASTER] Worker ' + worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal); workers = workers.filter(function (w) { return w && w !== worker; }); //console.log('WARNING: worker spawning turned off for debugging '); fork(); }); fork();