implement caching for /api/config responses

pull/1/head
ansuz 5 years ago
parent 0989595358
commit 74771f13f5

@ -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…
Cancel
Save