walnut.js/boot/master.js

127 lines
3.7 KiB
JavaScript
Raw Normal View History

'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!');
2016-03-29 01:12:35 +00:00
var path = require('path');
var cluster = require('cluster');
//var minWorkers = 2;
2015-11-19 07:42:20 +00:00
var numCores = 2; // Math.max(minWorkers, require('os').cpus().length);
var workers = [];
2015-11-28 05:44:52 +00:00
var config = require('../../config');
var useCaddy = require('fs').existsSync(config.caddy.bin);
var conf = {
2015-11-23 08:45:20 +00:00
localPort: process.argv[2] || (useCaddy ? 4080 : 443) // system / local network
, insecurePort: process.argv[3] || (useCaddy ? 80 : 80) // meh
, externalPort: 443 // world accessible
2015-11-23 08:45:20 +00:00
, externalPortInsecure: 80 // world accessible
// TODO externalInsecurePort?
, locked: false // TODO XXX
, ipcKey: null
2015-11-28 05:44:52 +00:00
, caddyfilepath: config.caddy.conf
2015-11-28 07:30:34 +00:00
// TODO needs mappings from db
, caddy: config.caddy
};
var state = {};
var caddy;
function fork() {
if (workers.length < numCores) {
workers.push(cluster.fork());
}
}
cluster.on('online', function (worker) {
// TODO XXX Should these be configurable? If so, where?
2016-03-29 01:12:35 +00:00
var certPaths = [
path.join(__dirname, 'certs', 'live')
, path.join(__dirname, 'letsencrypt', 'live')
];
var info;
2015-11-28 05:06:19 +00:00
conf.ddns = config.ddns;
conf.redirects = config.redirects;
console.info('[MASTER] Worker ' + worker.process.pid + ' is online');
2015-11-06 01:00:22 +00:00
fork();
// TODO communicate config with environment vars?
info = {
2015-11-28 06:05:27 +00:00
type: 'walnut.init'
, conf: {
protocol: useCaddy ? 'http' : 'https'
, externalPort: conf.externalPort
, localPort: conf.localPort
, insecurePort: conf.insecurePort
, trustProxy: useCaddy ? true : false
, certPaths: useCaddy ? null : certPaths
, ipcKey: null
// TODO let this load after server is listening
, redirects: config.redirects
2015-11-28 05:06:19 +00:00
, ddns: config.ddns
2015-12-04 07:00:30 +00:00
, 'org.oauth3.consumer': config['org.oauth3.consumer']
, 'org.oauth3.provider': config['org.oauth3.provider']
, keys: config.keys
}
};
worker.send(info);
function touchMaster(msg) {
2015-11-28 06:05:27 +00:00
if ('walnut.webserver.listening' !== msg.type) {
console.warn('[MASTER] received unexpected message from worker');
console.warn(msg);
return;
}
// calls init if init has not been called
state.caddy = caddy;
state.workers = workers;
require('../lib/master').touch(conf, state).then(function () {
2015-11-28 06:05:27 +00:00
info.type = 'walnut.webserver.onrequest';
info.conf.ipcKey = conf.ipcKey;
2015-11-12 11:14:59 +00:00
info.conf.memstoreSock = conf.memstoreSock;
info.conf.sqlite3Sock = conf.sqlite3Sock;
2015-11-18 11:44:22 +00:00
// TODO get this from db config instead
2015-11-19 22:13:20 +00:00
var config = require('../../config');
2015-11-28 05:44:52 +00:00
info.conf.primaryNameserver = config.ddns.primaryNameserver;
info.conf.nameservers = config.ddns.nameservers;
2015-11-19 12:34:59 +00:00
// TODO get this from db config instead
info.conf.privkey = config.privkey;
info.conf.pubkey = config.pubkey;
info.conf.redirects = config.redirects;
2015-11-28 05:06:19 +00:00
info.conf.ddns = config.ddns;
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.map(function (w) {
if (worker !== w) {
return w;
}
return null;
}).filter(function (w) {
return w;
});
2015-11-19 07:42:20 +00:00
//console.log('WARNING: worker spawning turned off for debugging ');
fork();
});
fork();
if (useCaddy) {
caddy = require('../lib/spawn-caddy').create(conf);
// relies on { localPort, locked }
caddy.spawn(conf);
}