From 548c48f5bf8ec1b353ef7c669f452a76f8fc7111 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 29 Mar 2015 03:29:40 +0000 Subject: [PATCH] fix race condition on boot --- lib/vhost-sni-server.js | 107 ++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/lib/vhost-sni-server.js b/lib/vhost-sni-server.js index ee03844..976cfda 100644 --- a/lib/vhost-sni-server.js +++ b/lib/vhost-sni-server.js @@ -61,6 +61,9 @@ module.exports.create = function (securePort, certsPath, vhostsdir) { + "" + "" ); + + // 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( - "" - + "" - + '' - + "" - + "" - + "Cannot " - + encodeURI(req.method) - + " 'https://" - + encodeURI(domaininfo.hostname) - + '/' - + encodeURI(domaininfo.pathname ? (domaininfo.pathname + '/') : '') - + encodeURI(req.url.replace(/^\//, '')) - + "'" - + "
" - + "
" - + "Domain: " + encodeURI(domaininfo.hostname) - + "
" - + "App: " + encodeURI(domaininfo.pathname) - + "
" - + "Route : " + encodeURI(req.url) - + "" - + "" - ); - /* - 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( + "" + + "" + + '' + + "" + + "" + + "Cannot " + + encodeURI(req.method) + + " 'https://" + + encodeURI(domaininfo.hostname) + + '/' + + encodeURI(domaininfo.pathname ? (domaininfo.pathname + '/') : '') + + encodeURI(req.url.replace(/^\//, '')) + + "'" + + "
" + + "
" + + "Domain: " + encodeURI(domaininfo.hostname) + + "
" + + "App: " + encodeURI(domaininfo.pathname) + + "
" + + "Route : " + encodeURI(req.url) + + "" + + "" + ); + })); })); })); } 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?