fix race condition on boot

This commit is contained in:
AJ ONeal 2015-03-29 03:29:40 +00:00
parent 45285b8409
commit 548c48f5bf
1 changed files with 64 additions and 43 deletions

View File

@ -61,6 +61,9 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
+ "</body>"
+ "</html>"
);
// for debugging only
throw err;
}
return next;
@ -79,7 +82,8 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
return new PromiseA(function (resolve) {
var forEachAsync = require('foreachasync').forEachAsync.create(PromiseA);
var connect = require('connect');
var app = connect();
// TODO make lazy
var app = connect().use(require('compression')());
var vhost = require('vhost');
var domainMergeMap = {};
@ -121,14 +125,12 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
console.log('[log] [once] Preparing mount for', domaininfo.hostname + '/' + domaininfo.dirpathname);
domainMergeMap[domaininfo.hostname].mountsMap['/' + domaininfo.dirpathname] = function (req, res, next) {
function nextify() {
if (appContext) {
appContext(req, res, next);
return;
}
function loadThatApp() {
var time = Date.now();
console.log('[log] LOADING "' + domaininfo.hostname + '/' + domaininfo.pathname + '"', req.url);
getAppContext(domaininfo).then(function (localApp) {
return getAppContext(domaininfo).then(function (localApp) {
console.info((Date.now() - time) + 'ms Loaded ' + domaininfo.hostname + ':' + securePort + '/' + domaininfo.pathname);
//if (localApp.arity >= 2) { /* connect uses .apply(null, arguments)*/ }
if ('function' !== typeof localApp) {
localApp = getDummyAppContext(null, "[ERROR] no connect-style export from " + domaininfo.dirname);
@ -146,44 +148,42 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
// TODO redirect GET /favicon.ico to GET (req.headers.referer||'') + /favicon.ico
// TODO other common root things - robots.txt, app-icon, etc
serveFavicon(req, res, handleAppScopedError(domaininfo, req, res, function (req, res) {
res.writeHead(404);
res.end(
"<html>"
+ "<head>"
+ '<link rel="icon" href="favicon.ico" />'
+ "</head>"
+ "<body>"
+ "Cannot "
+ encodeURI(req.method)
+ " 'https://"
+ encodeURI(domaininfo.hostname)
+ '/'
+ encodeURI(domaininfo.pathname ? (domaininfo.pathname + '/') : '')
+ encodeURI(req.url.replace(/^\//, ''))
+ "'"
+ "<br/>"
+ "<br/>"
+ "Domain: " + encodeURI(domaininfo.hostname)
+ "<br/>"
+ "App: " + encodeURI(domaininfo.pathname)
+ "<br/>"
+ "Route : " + encodeURI(req.url)
+ "</body>"
+ "</html>"
);
/*
res.end('{ "error": { "messages": "Route matched '
+ domaininfo.hostname + '/' + domaininfo.pathname
+ ', but was not handled. Forcing hard stop to prevent fallthru." } }');
*/
connectContext.static(req, res, handleAppScopedError(domaininfo, req, res, function (req, res) {
res.writeHead(404);
res.end(
"<html>"
+ "<head>"
+ '<link rel="icon" href="favicon.ico" />'
+ "</head>"
+ "<body>"
+ "Cannot "
+ encodeURI(req.method)
+ " 'https://"
+ encodeURI(domaininfo.hostname)
+ '/'
+ encodeURI(domaininfo.pathname ? (domaininfo.pathname + '/') : '')
+ encodeURI(req.url.replace(/^\//, ''))
+ "'"
+ "<br/>"
+ "<br/>"
+ "Domain: " + encodeURI(domaininfo.hostname)
+ "<br/>"
+ "App: " + encodeURI(domaininfo.pathname)
+ "<br/>"
+ "Route : " + encodeURI(req.url)
+ "</body>"
+ "</html>"
);
}));
}));
}));
}
try {
domainMergeMap[domaininfo.hostname].apps.use('/' + domaininfo.pathname, localAppWrapped);
console.info('Loaded ' + domaininfo.hostname + ':' + securePort + '/' + domaininfo.pathname);
appContext = localAppWrapped;
appContext(req, res, next);
var localConnect = connect();
localConnect.use(require('connect-query')());
localConnect.use(localAppWrapped);
domainMergeMap[domaininfo.hostname].apps.use('/' + domaininfo.pathname, localConnect);
return localConnect;
} catch(e) {
console.error('[ERROR] '
+ domaininfo.hostname + ':' + securePort
@ -199,6 +199,21 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
});
}
function nextify() {
if (!appContext) {
appContext = loadThatApp();
}
if (!appContext.then) {
appContext(req, res, next);
} else {
appContext.then(function (localConnect) {
appContext = localConnect;
appContext(req, res, next);
});
}
}
if (!serveStatic) {
serveStatic = require('serve-static');
}
@ -251,7 +266,7 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
return function (req, res) {
res.writeHead(500);
res.end('{ "error": { "message": "' + msg + '" } }');
}
};
}
function getAppContext(domaininfo) {
@ -279,6 +294,9 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
localApp = PromiseA.resolve(localApp);
} else {
return localApp.catch(function (e) {
console.error("[ERROR] initialization failed during create() for " + domaininfo.dirname);
console.error(e);
throw e;
return getDummyAppContext(e, "[ERROR] initialization failed during create() for " + domaininfo.dirname);
});
}
@ -303,6 +321,7 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
});
}
/*
function hotloadApp(req, res, next) {
var forEachAsync = require('foreachasync').forEachAsync.create(PromiseA);
var vhost = (req.headers.host || '').split(':')[0];
@ -347,8 +366,10 @@ module.exports.create = function (securePort, certsPath, vhostsdir) {
if (!domainMergeMap[domaininfo.hostname]) {
// TODO reread directories
}
*/
*/ //
/*
}
*/
// TODO pre-cache these once the server has started?