implement caching for /api/config responses
This commit is contained in:
parent
0989595358
commit
74771f13f5
101
server.js
101
server.js
@ -7,6 +7,7 @@ var Fs = require('fs');
|
|||||||
var Package = require('./package.json');
|
var Package = require('./package.json');
|
||||||
var Path = require("path");
|
var Path = require("path");
|
||||||
var nThen = require("nthen");
|
var nThen = require("nthen");
|
||||||
|
var Util = require("./lib/common-util");
|
||||||
|
|
||||||
var config = require("./lib/load-config");
|
var config = require("./lib/load-config");
|
||||||
|
|
||||||
@ -34,7 +35,9 @@ if (process.env.PACKAGE) {
|
|||||||
FRESH_KEY = +new Date();
|
FRESH_KEY = +new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var configCache = {};
|
||||||
config.flushCache = function () {
|
config.flushCache = function () {
|
||||||
|
configCache = {};
|
||||||
FRESH_KEY = +new Date();
|
FRESH_KEY = +new Date();
|
||||||
if (!(DEV_MODE || FRESH_MODE)) { FRESH_MODE = true; }
|
if (!(DEV_MODE || FRESH_MODE)) { FRESH_MODE = true; }
|
||||||
if (!config.log) { return; }
|
if (!config.log) { return; }
|
||||||
@ -143,38 +146,72 @@ try {
|
|||||||
});
|
});
|
||||||
} catch (e) { console.error("Can't parse admin keys"); }
|
} catch (e) { console.error("Can't parse admin keys"); }
|
||||||
|
|
||||||
// TODO, cache this /api/config responses instead of re-computing it each time
|
var serveConfig = (function () {
|
||||||
app.get('/api/config', function(req, res){
|
// if dev mode: never cache
|
||||||
// TODO precompute any data that isn't dynamic to save some CPU time
|
var cacheString = function () {
|
||||||
var host = req.headers.host.replace(/\:[0-9]+/, '');
|
return (FRESH_KEY? '-' + FRESH_KEY: '') + (DEV_MODE? '-' + (+new Date()): '');
|
||||||
res.setHeader('Content-Type', 'text/javascript');
|
};
|
||||||
res.send('define(function(){\n' + [
|
|
||||||
'var obj = ' + JSON.stringify({
|
var template = function (host) {
|
||||||
requireConf: {
|
return [
|
||||||
waitSeconds: 600,
|
'define(function(){',
|
||||||
urlArgs: 'ver=' + Package.version + (FRESH_KEY? '-' + FRESH_KEY: '') + (DEV_MODE? '-' + (+new Date()): ''),
|
'var obj = ' + JSON.stringify({
|
||||||
},
|
requireConf: {
|
||||||
removeDonateButton: (config.removeDonateButton === true),
|
waitSeconds: 600,
|
||||||
allowSubscriptions: (config.allowSubscriptions === true),
|
urlArgs: 'ver=' + Package.version + cacheString(),
|
||||||
websocketPath: config.externalWebsocketURL,
|
},
|
||||||
httpUnsafeOrigin: config.httpUnsafeOrigin.replace(/^\s*/, ''),
|
removeDonateButton: (config.removeDonateButton === true),
|
||||||
adminEmail: config.adminEmail,
|
allowSubscriptions: (config.allowSubscriptions === true),
|
||||||
adminKeys: admins,
|
websocketPath: config.externalWebsocketURL,
|
||||||
inactiveTime: config.inactiveTime,
|
httpUnsafeOrigin: config.httpUnsafeOrigin.replace(/^\s*/, ''),
|
||||||
supportMailbox: config.supportMailboxPublicKey
|
adminEmail: config.adminEmail,
|
||||||
}, null, '\t'),
|
adminKeys: admins,
|
||||||
'obj.httpSafeOrigin = ' + (function () {
|
inactiveTime: config.inactiveTime,
|
||||||
if (config.httpSafeOrigin) { return '"' + config.httpSafeOrigin + '"'; }
|
supportMailbox: config.supportMailboxPublicKey
|
||||||
if (config.httpSafePort) {
|
}, null, '\t'),
|
||||||
return "(function () { return window.location.origin.replace(/\:[0-9]+$/, ':" +
|
'obj.httpSafeOrigin = ' + (function () {
|
||||||
config.httpSafePort + "'); }())";
|
if (config.httpSafeOrigin) { return '"' + config.httpSafeOrigin + '"'; }
|
||||||
}
|
if (config.httpSafePort) {
|
||||||
return 'window.location.origin';
|
return "(function () { return window.location.origin.replace(/\:[0-9]+$/, ':" +
|
||||||
}()),
|
config.httpSafePort + "'); }())";
|
||||||
'return obj',
|
}
|
||||||
'});'
|
return 'window.location.origin';
|
||||||
].join(';\n'));
|
}()),
|
||||||
});
|
'return obj',
|
||||||
|
'});'
|
||||||
|
].join(';\n')
|
||||||
|
};
|
||||||
|
|
||||||
|
var cleanUp = {};
|
||||||
|
|
||||||
|
return function (req, res) {
|
||||||
|
var host = req.headers.host.replace(/\:[0-9]+/, '');
|
||||||
|
res.setHeader('Content-Type', 'text/javascript');
|
||||||
|
// don't cache anything if you're in dev mode
|
||||||
|
if (DEV_MODE) {
|
||||||
|
return void res.send(template(host));
|
||||||
|
}
|
||||||
|
// generate a lookup key for the cache
|
||||||
|
var cacheKey = host + ':' + cacheString();
|
||||||
|
// if there's nothing cached for that key...
|
||||||
|
if (!configCache[cacheKey]) {
|
||||||
|
// generate the response and cache it in memory
|
||||||
|
configCache[cacheKey] = template(host);
|
||||||
|
// and create a function to conditionally evict cache entries
|
||||||
|
// which have not been accessed in the last 20 seconds
|
||||||
|
cleanUp[cacheKey] = Util.throttle(function () {
|
||||||
|
delete cleanUp[cacheKey];
|
||||||
|
delete configCache[cacheKey];
|
||||||
|
}, 20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// successive calls to this function
|
||||||
|
cleanUp[cacheKey]();
|
||||||
|
return void res.send(configCache[cacheKey]);
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
app.get('/api/config', serveConfig);
|
||||||
|
|
||||||
var four04_path = Path.resolve(__dirname + '/customize.dist/404.html');
|
var four04_path = Path.resolve(__dirname + '/customize.dist/404.html');
|
||||||
var custom_four04_path = Path.resolve(__dirname + '/customize/404.html');
|
var custom_four04_path = Path.resolve(__dirname + '/customize/404.html');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user