94 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			94 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'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();
 |