mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 03:55:55 +01:00
fix: guest header/footer cache
allow clearing individual caches
This commit is contained in:
@@ -2,10 +2,5 @@
|
|||||||
"post-cache": "Post Cache",
|
"post-cache": "Post Cache",
|
||||||
"percent-full": "%1% Full",
|
"percent-full": "%1% Full",
|
||||||
"post-cache-size": "Post Cache Size",
|
"post-cache-size": "Post Cache Size",
|
||||||
"items-in-cache": "Items in Cache",
|
"items-in-cache": "Items in Cache"
|
||||||
"control-panel": "Control Panel",
|
|
||||||
"update-settings": "Update Cache Settings",
|
|
||||||
"clear": "Clear",
|
|
||||||
"download": "Download",
|
|
||||||
"enabled": "Enabled"
|
|
||||||
}
|
}
|
||||||
@@ -7,14 +7,16 @@ define('admin/advanced/cache', function () {
|
|||||||
Settings.prepare();
|
Settings.prepare();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#clear').on('click', function () {
|
$('.clear').on('click', function () {
|
||||||
socket.emit('admin.cache.clear', function (err) {
|
var name = $(this).attr('data-name');
|
||||||
|
socket.emit('admin.cache.clear', { name: name }, function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return app.alertError(err.message);
|
return app.alertError(err.message);
|
||||||
}
|
}
|
||||||
ajaxify.refresh();
|
ajaxify.refresh();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('.checkbox').on('change', function () {
|
$('.checkbox').on('change', function () {
|
||||||
var input = $(this).find('input');
|
var input = $(this).find('input');
|
||||||
var flag = input.is(':checked');
|
var flag = input.is(':checked');
|
||||||
|
|||||||
@@ -9,56 +9,30 @@ cacheController.get = function (req, res) {
|
|||||||
const groupCache = require('../../groups').cache;
|
const groupCache = require('../../groups').cache;
|
||||||
const objectCache = require('../../database').objectCache;
|
const objectCache = require('../../database').objectCache;
|
||||||
const localCache = require('../../cache');
|
const localCache = require('../../cache');
|
||||||
|
const headerFooterCache = require('../../middleware').headerFooterCache;
|
||||||
|
|
||||||
let percentFull = 0;
|
function getInfo(cache) {
|
||||||
if (postCache.itemCount > 0) {
|
return {
|
||||||
percentFull = ((postCache.length / postCache.max) * 100).toFixed(2);
|
length: cache.length,
|
||||||
|
max: cache.max,
|
||||||
|
itemCount: cache.itemCount,
|
||||||
|
percentFull: ((cache.length / cache.max) * 100).toFixed(2),
|
||||||
|
hits: utils.addCommas(String(cache.hits)),
|
||||||
|
misses: utils.addCommas(String(cache.misses)),
|
||||||
|
hitRatio: ((cache.hits / (cache.hits + cache.misses) || 0)).toFixed(4),
|
||||||
|
enabled: cache.enabled,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
postCache: {
|
postCache: getInfo(postCache),
|
||||||
length: postCache.length,
|
groupCache: getInfo(groupCache),
|
||||||
max: postCache.max,
|
localCache: getInfo(localCache),
|
||||||
itemCount: postCache.itemCount,
|
headerFooterCache: getInfo(headerFooterCache),
|
||||||
percentFull: percentFull,
|
|
||||||
hits: utils.addCommas(String(postCache.hits)),
|
|
||||||
misses: utils.addCommas(String(postCache.misses)),
|
|
||||||
hitRatio: ((postCache.hits / (postCache.hits + postCache.misses) || 0)).toFixed(4),
|
|
||||||
enabled: postCache.enabled,
|
|
||||||
},
|
|
||||||
groupCache: {
|
|
||||||
length: groupCache.length,
|
|
||||||
max: groupCache.max,
|
|
||||||
itemCount: groupCache.itemCount,
|
|
||||||
percentFull: ((groupCache.length / groupCache.max) * 100).toFixed(2),
|
|
||||||
hits: utils.addCommas(String(groupCache.hits)),
|
|
||||||
misses: utils.addCommas(String(groupCache.misses)),
|
|
||||||
hitRatio: (groupCache.hits / (groupCache.hits + groupCache.misses)).toFixed(4),
|
|
||||||
enabled: groupCache.enabled,
|
|
||||||
},
|
|
||||||
localCache: {
|
|
||||||
length: localCache.length,
|
|
||||||
max: localCache.max,
|
|
||||||
itemCount: localCache.itemCount,
|
|
||||||
percentFull: ((localCache.length / localCache.max) * 100).toFixed(2),
|
|
||||||
hits: utils.addCommas(String(localCache.hits)),
|
|
||||||
misses: utils.addCommas(String(localCache.misses)),
|
|
||||||
hitRatio: ((localCache.hits / (localCache.hits + localCache.misses) || 0)).toFixed(4),
|
|
||||||
enabled: localCache.enabled,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (objectCache) {
|
if (objectCache) {
|
||||||
data.objectCache = {
|
data.objectCache = getInfo(objectCache);
|
||||||
length: objectCache.length,
|
|
||||||
max: objectCache.max,
|
|
||||||
itemCount: objectCache.itemCount,
|
|
||||||
percentFull: ((objectCache.length / objectCache.max) * 100).toFixed(2),
|
|
||||||
hits: utils.addCommas(String(objectCache.hits)),
|
|
||||||
misses: utils.addCommas(String(objectCache.misses)),
|
|
||||||
hitRatio: (objectCache.hits / (objectCache.hits + objectCache.misses)).toFixed(4),
|
|
||||||
enabled: objectCache.enabled,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.render('admin/advanced/cache', data);
|
res.render('admin/advanced/cache', data);
|
||||||
@@ -70,6 +44,7 @@ cacheController.dump = function (req, res, next) {
|
|||||||
object: require('../../database').objectCache,
|
object: require('../../database').objectCache,
|
||||||
group: require('../../groups').cache,
|
group: require('../../groups').cache,
|
||||||
local: require('../../cache'),
|
local: require('../../cache'),
|
||||||
|
headerfooter: require('../../middleware').headerFooterCache,
|
||||||
};
|
};
|
||||||
if (!caches[req.query.name]) {
|
if (!caches[req.query.name]) {
|
||||||
return next();
|
return next();
|
||||||
|
|||||||
@@ -10,11 +10,18 @@ const translator = require('../translator');
|
|||||||
const widgets = require('../widgets');
|
const widgets = require('../widgets');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const slugify = require('../slugify');
|
const slugify = require('../slugify');
|
||||||
const cache = require('../cache');
|
const cacheCreate = require('../cacheCreate');
|
||||||
|
const cache = cacheCreate({
|
||||||
|
name: 'header-footer',
|
||||||
|
max: 1000,
|
||||||
|
maxAge: 0,
|
||||||
|
});
|
||||||
|
|
||||||
const relative_path = nconf.get('relative_path');
|
const relative_path = nconf.get('relative_path');
|
||||||
|
|
||||||
module.exports = function (middleware) {
|
module.exports = function (middleware) {
|
||||||
|
middleware.headerFooterCache = cache;
|
||||||
|
|
||||||
middleware.processRender = function processRender(req, res, next) {
|
middleware.processRender = function processRender(req, res, next) {
|
||||||
// res.render post-processing, modified from here: https://gist.github.com/mrlannigan/5051687
|
// res.render post-processing, modified from here: https://gist.github.com/mrlannigan/5051687
|
||||||
const render = res.render;
|
const render = res.render;
|
||||||
@@ -97,8 +104,15 @@ module.exports = function (middleware) {
|
|||||||
async function renderHeaderFooter(method, req, res, options) {
|
async function renderHeaderFooter(method, req, res, options) {
|
||||||
let str = '';
|
let str = '';
|
||||||
const lang = getLang(req, res);
|
const lang = getLang(req, res);
|
||||||
|
function getCacheKey() {
|
||||||
|
return [lang, method]
|
||||||
|
.concat(req.path.split('/').slice(0, 4))
|
||||||
|
.join('/');
|
||||||
|
}
|
||||||
|
let cacheKey;
|
||||||
if (req.uid === 0 && res.locals.renderHeader) {
|
if (req.uid === 0 && res.locals.renderHeader) {
|
||||||
str = cache.get('render' + options.template.name + lang + method);
|
cacheKey = getCacheKey();
|
||||||
|
str = cache.get(cacheKey);
|
||||||
if (str) {
|
if (str) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -114,7 +128,7 @@ module.exports = function (middleware) {
|
|||||||
}
|
}
|
||||||
const translated = await translate(str, lang);
|
const translated = await translate(str, lang);
|
||||||
if (req.uid === 0 && res.locals.renderHeader) {
|
if (req.uid === 0 && res.locals.renderHeader) {
|
||||||
cache.set('render' + options.template.name + lang + method, translated, 300000);
|
cache.set(cacheKey, translated, 300000);
|
||||||
}
|
}
|
||||||
return translated;
|
return translated;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,18 @@
|
|||||||
|
|
||||||
const SocketCache = module.exports;
|
const SocketCache = module.exports;
|
||||||
|
|
||||||
SocketCache.clear = async function () {
|
SocketCache.clear = async function (socket, data) {
|
||||||
require('../../posts/cache').reset();
|
if (data.name === 'post') {
|
||||||
require('../../database').objectCache.reset();
|
require('../../posts/cache').reset();
|
||||||
require('../../groups').cache.reset();
|
} else if (data.name === 'object') {
|
||||||
require('../../cache').reset();
|
require('../../database').objectCache.reset();
|
||||||
|
} else if (data.name === 'group') {
|
||||||
|
require('../../groups').cache.reset();
|
||||||
|
} else if (data.name === 'local') {
|
||||||
|
require('../../cache').reset();
|
||||||
|
} else if (data.name === 'headerfooter') {
|
||||||
|
require('../../middleware').headerFooterCache.reset();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketCache.toggle = async function (socket, data) {
|
SocketCache.toggle = async function (socket, data) {
|
||||||
@@ -15,6 +22,7 @@ SocketCache.toggle = async function (socket, data) {
|
|||||||
object: require('../../database').objectCache,
|
object: require('../../database').objectCache,
|
||||||
group: require('../../groups').cache,
|
group: require('../../groups').cache,
|
||||||
local: require('../../cache'),
|
local: require('../../cache'),
|
||||||
|
headerfooter: require('../../middleware').headerFooterCache,
|
||||||
};
|
};
|
||||||
if (!caches[data.name]) {
|
if (!caches[data.name]) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
|
|
||||||
<div class="row post-cache">
|
<div class="row post-cache">
|
||||||
<div class="col-lg-9">
|
<div class="col-lg-12">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-2">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><i class="fa fa-calendar-o"></i> [[admin/advanced/cache:post-cache]]</div>
|
<div class="panel-heading">[[admin/advanced/cache:post-cache]]</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="checkbox" data-name="post">
|
<div class="checkbox" data-name="post">
|
||||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input class="mdl-switch__input" type="checkbox" {{{if postCache.enabled}}}checked{{{end}}}>
|
<input class="mdl-switch__input" type="checkbox" {{{if postCache.enabled}}}checked{{{end}}}>
|
||||||
<span class="mdl-switch__label"><strong>[[admin/advanced/cache:enabled]]</strong></span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -31,20 +30,20 @@
|
|||||||
<label for="postCacheSize">[[admin/advanced/cache:post-cache-size]]</label>
|
<label for="postCacheSize">[[admin/advanced/cache:post-cache-size]]</label>
|
||||||
<input id="postCacheSize" type="text" class="form-control" value="" data-field="postCacheSize">
|
<input id="postCacheSize" type="text" class="form-control" value="" data-field="postCacheSize">
|
||||||
</div>
|
</div>
|
||||||
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=post" class="btn btn-default"><i class="fa fa-download"></i> [[admin/advanced/cache:download]]</a>
|
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=post" class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>
|
||||||
|
<a class="btn btn-sm btn-danger clear" data-name="post"><i class="fa fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- IF objectCache -->
|
<!-- IF objectCache -->
|
||||||
<div class="col-lg-3">
|
<div class="col-lg-2">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><i class="fa fa-calendar-o"></i> Object Cache</div>
|
<div class="panel-heading">Object Cache</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="checkbox" data-name="object">
|
<div class="checkbox" data-name="object">
|
||||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input class="mdl-switch__input" type="checkbox" {{{if objectCache.enabled}}}checked{{{end}}}>
|
<input class="mdl-switch__input" type="checkbox" {{{if objectCache.enabled}}}checked{{{end}}}>
|
||||||
<span class="mdl-switch__label"><strong>[[admin/advanced/cache:enabled]]</strong></span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span>{objectCache.length} / {objectCache.max}</span><br/>
|
<span>{objectCache.length} / {objectCache.max}</span><br/>
|
||||||
@@ -57,19 +56,20 @@
|
|||||||
<label>Hits:</label> <span>{objectCache.hits}</span><br/>
|
<label>Hits:</label> <span>{objectCache.hits}</span><br/>
|
||||||
<label>Misses:</label> <span>{objectCache.misses}</span><br/>
|
<label>Misses:</label> <span>{objectCache.misses}</span><br/>
|
||||||
<label>Hit Ratio:</label> <span>{objectCache.hitRatio}</span><br/>
|
<label>Hit Ratio:</label> <span>{objectCache.hitRatio}</span><br/>
|
||||||
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=object" class="btn btn-default"><i class="fa fa-download"></i> [[admin/advanced/cache:download]]</a>
|
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=object" class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>
|
||||||
|
<a class="btn btn-sm btn-danger clear" data-name="object"><i class="fa fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- ENDIF objectCache -->
|
<!-- ENDIF objectCache -->
|
||||||
<div class="col-lg-3">
|
|
||||||
|
<div class="col-lg-2">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><i class="fa fa-calendar-o"></i> Group Cache</div>
|
<div class="panel-heading">Group Cache</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="checkbox" data-name="group">
|
<div class="checkbox" data-name="group">
|
||||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input class="mdl-switch__input" type="checkbox" {{{if groupCache.enabled}}}checked{{{end}}}>
|
<input class="mdl-switch__input" type="checkbox" {{{if groupCache.enabled}}}checked{{{end}}}>
|
||||||
<span class="mdl-switch__label"><strong>[[admin/advanced/cache:enabled]]</strong></span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span>{groupCache.length} / {groupCache.max}</span><br/>
|
<span>{groupCache.length} / {groupCache.max}</span><br/>
|
||||||
@@ -83,18 +83,19 @@
|
|||||||
<label>Hits:</label> <span>{groupCache.hits}</span><br/>
|
<label>Hits:</label> <span>{groupCache.hits}</span><br/>
|
||||||
<label>Misses:</label> <span>{groupCache.misses}</span><br/>
|
<label>Misses:</label> <span>{groupCache.misses}</span><br/>
|
||||||
<label>Hit Ratio:</label> <span>{groupCache.hitRatio}</span><br/>
|
<label>Hit Ratio:</label> <span>{groupCache.hitRatio}</span><br/>
|
||||||
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=group" class="btn btn-default"><i class="fa fa-download"></i> [[admin/advanced/cache:download]]</a>
|
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=group" class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>
|
||||||
|
<a class="btn btn-sm btn-danger clear" data-name="group"><i class="fa fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3">
|
|
||||||
|
<div class="col-lg-2">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><i class="fa fa-calendar-o"></i> Local Cache</div>
|
<div class="panel-heading">Local Cache</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="checkbox" data-name="local">
|
<div class="checkbox" data-name="local">
|
||||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
<input class="mdl-switch__input" type="checkbox" {{{if localCache.enabled}}}checked{{{end}}}>
|
<input class="mdl-switch__input" type="checkbox" {{{if localCache.enabled}}}checked{{{end}}}>
|
||||||
<span class="mdl-switch__label"><strong>[[admin/advanced/cache:enabled]]</strong></span>
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<span>{localCache.length} / {localCache.max}</span><br/>
|
<span>{localCache.length} / {localCache.max}</span><br/>
|
||||||
@@ -108,19 +109,42 @@
|
|||||||
<label>Hits:</label> <span>{localCache.hits}</span><br/>
|
<label>Hits:</label> <span>{localCache.hits}</span><br/>
|
||||||
<label>Misses:</label> <span>{localCache.misses}</span><br/>
|
<label>Misses:</label> <span>{localCache.misses}</span><br/>
|
||||||
<label>Hit Ratio:</label> <span>{localCache.hitRatio}</span><br/>
|
<label>Hit Ratio:</label> <span>{localCache.hitRatio}</span><br/>
|
||||||
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=local" class="btn btn-default"><i class="fa fa-download"></i> [[admin/advanced/cache:download]]</a>
|
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=local" class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>
|
||||||
|
<a class="btn btn-sm btn-danger clear" data-name="local"><i class="fa fa-trash"></i></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-2">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">Header Footer Cache</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="checkbox" data-name="headerfooter">
|
||||||
|
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||||
|
<input class="mdl-switch__input" type="checkbox" {{{if headerFooterCache.enabled}}}checked{{{end}}}>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<span>{headerFooterCache.length} / {headerFooterCache.max}</span><br/>
|
||||||
|
|
||||||
|
<div class="progress">
|
||||||
|
<div class="progress-bar" role="progressbar" aria-valuenow="{headerFooterCache.percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {headerFooterCache.percentFull}%;">
|
||||||
|
[[admin/advanced/cache:percent-full, {headerFooterCache.percentFull}]]
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Hits:</label> <span>{headerFooterCache.hits}</span><br/>
|
||||||
|
<label>Misses:</label> <span>{headerFooterCache.misses}</span><br/>
|
||||||
|
<label>Hit Ratio:</label> <span>{headerFooterCache.hitRatio}</span><br/>
|
||||||
|
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name=headerfooter" class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>
|
||||||
|
<a class="btn btn-sm btn-danger clear" data-name="headerfooter"><i class="fa fa-trash"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-3 acp-sidebar">
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">[[admin/advanced/cache:control-panel]]</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<button class="btn btn-primary btn-block" id="save">[[admin/advanced/cache:update-settings]]</button>
|
|
||||||
<button class="btn btn-info btn-block" id="clear">[[admin/advanced/cache:clear]]</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<button id="save" class="floating-button mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
|
||||||
|
<i class="material-icons">save</i>
|
||||||
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user