diff --git a/boot/master.js b/boot/master.js index e6d904b..92b2598 100644 --- a/boot/master.js +++ b/boot/master.js @@ -12,7 +12,7 @@ console.info('\n\n\n[MASTER] Welcome to WALNUT!'); var cluster = require('cluster'); var path = require('path'); //var minWorkers = 2; -var numCores = 1; // Math.max(minWorkers, require('os').cpus().length); +var numCores = 2; // Math.max(minWorkers, require('os').cpus().length); var workers = []; var caddypath = '/usr/local/bin/caddy'; var useCaddy = require('fs').existsSync(caddypath); @@ -100,8 +100,8 @@ cluster.on('exit', function (worker, code, signal) { return w; }); - console.log('WARNING: worker spawning turned off for debugging '); - //fork(); + //console.log('WARNING: worker spawning turned off for debugging '); + fork(); }); fork(); diff --git a/lib/api-server.js b/lib/api-server.js index 2ab22ce..3ab23c0 100644 --- a/lib/api-server.js +++ b/lib/api-server.js @@ -2,29 +2,34 @@ // TODO handle static app urls? // NOTE rejecting non-api urls should happen before this -module.exports.create = function (conf, deps, app) { +module.exports.create = function (conf, deps/*, Services*/) { + var PromiseA = deps.Promise; + var app = deps.app; + var express = deps.express; var escapeStringRegexp = require('escape-string-regexp'); var vhostsMap = conf.vhostsMap; - if (!app) { - app = deps.app; - } function getApi(route) { // TODO don't modify route, modify some other variable instead - var PromiseA = require('bluebird'); var path = require('path'); // TODO needs some version stuff (which would also allow hot-loading of updates) // TODO version could be tied to sha256sum var pkgpath = path.join(conf.apipath, (route.api.package || route.api.id), (route.api.version || '')); return new PromiseA(function (resolve, reject) { + var myApp; + try { // TODO dynamic requires are a no-no // can we statically generate a require-er? on each install? // module.exports = { {{pkgpath}}: function () { return require({{pkgpath}}) } } // requirer[pkgpath]() - route.route = require(pkgpath).create(conf, deps, app); + myApp = express(); + if (app.get('trust proxy')) { + myApp.set('trust proxy', app.get('trust proxy')); + } + route.route = require(pkgpath).create(conf, deps, myApp); } catch(e) { reject(e); return; @@ -50,8 +55,10 @@ module.exports.create = function (conf, deps, app) { pathname = '/api'; } if (-1 === pathname.indexOf('/api')) { + // TODO needs namespace for current api pathname = '/api' + pathname; } + // pathname += '.local'; if (!route.re) { route.re = new RegExp(escapeStringRegexp(pathname) + '(#|\\/|\\?|$)'); @@ -62,7 +69,8 @@ module.exports.create = function (conf, deps, app) { // re.test("/api/foo") // re.test("/apifoo") // false if (route.re.test(req.url)) { - apps = route.apps; + // make a copy + apps = route.apps.slice(0); return true; } }); @@ -90,11 +98,17 @@ module.exports.create = function (conf, deps, app) { } if (route.route) { + if (route.route.then) { + route.route.then(function (expressApp) { + expressApp(req, res, nextify); + }); + return; + } route.route(req, res, nextify); return; } - if (route._errored) { + if (route._errored) { nextify(new Error("couldn't load api")); return; } @@ -104,16 +118,20 @@ module.exports.create = function (conf, deps, app) { return; } - getApi(route).then(function (route) { + return getApi(route).then(function (expressApp) { try { - route(req, res, nextify); - route.route = route; + expressApp(req, res, nextify); + route.route = expressApp; } catch(e) { route._errored = true; console.error('[App Load Error]'); - console.error(e.stack); nextify(new Error("couldn't load api")); } + + return expressApp; + }, function (err) { + console.error('[App Promise Error]'); + nextify(err); }); } diff --git a/lib/worker.js b/lib/worker.js index 305ef1b..a282d64 100644 --- a/lib/worker.js +++ b/lib/worker.js @@ -173,8 +173,6 @@ module.exports.create = function (webserver, info, state) { }); function handleApi(req, res, next) { - var myApp; - if (!/^\/api/.test(req.url)) { next(); return; @@ -189,25 +187,21 @@ module.exports.create = function (webserver, info, state) { } if (apiHandler) { + /* if (apiHandler.then) { apiHandler.then(function (myApp) { myApp(req, res, next); }); return; } + */ apiHandler(req, res, next); return; } - // apiHandler = require('./vhost-server').create(info.conf.localPort, vhostsdir).create(webserver, app) - myApp = express(); - if (app.get('trust proxy')) { - myApp.set('trust proxy', app.get('trust proxy')); - } apiHandler = require('./api-server').create(apiConf, { - app: myApp - , memstore: memstore + memstore: memstore , sqlstores: sqlstores , clientSqlFactory: clientFactory , systemSqlFactory: systemFactory @@ -215,6 +209,8 @@ module.exports.create = function (webserver, info, state) { //, handleRejection: require('./lib/common').rejectableRequest; //, localPort: info.conf.localPort , Promise: PromiseA + , express: express + , app: app }, Services).api; apiHandler(req, res, next); @@ -248,6 +244,15 @@ module.exports.create = function (webserver, info, state) { .use(require('connect-send-error').error()) ; app.use('/', handleApi); + app.use('/', function (err, req, res, next) { + console.error('[Error Handler]'); + console.error(err.stack); + if (req.xhr) { + res.send({ error: { message: "kinda unknownish error" } }); + } else { + res.send('