mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
feat: allow plugins to add to admin cache list (#10833)
* feat: allow plugins to add to admin cache list resolves #10820 plugins will have to use `filter:admin.cache.get` hook and just add their own cache to the object there. * feat: add dump to ttlCache and expose properties * feat: also expose properties under their current names * feat: display TTL if set
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"post-cache": "Post Cache",
|
||||
"group-cache": "Group Cache",
|
||||
"local-cache": "Local Cache",
|
||||
"object-cache": "Object Cache",
|
||||
"percent-full": "%1% Full",
|
||||
"post-cache-size": "Post Cache Size",
|
||||
"items-in-cache": "Items in Cache"
|
||||
|
||||
5
src/cache/lru.js
vendored
5
src/cache/lru.js
vendored
@@ -37,12 +37,15 @@ module.exports = function (opts) {
|
||||
cache.enabled = opts.hasOwnProperty('enabled') ? opts.enabled : true;
|
||||
const cacheSet = lruCache.set;
|
||||
|
||||
// backwards compatibility
|
||||
// expose properties while keeping backwards compatibility
|
||||
const propertyMap = new Map([
|
||||
['length', 'calculatedSize'],
|
||||
['calculatedSize', 'calculatedSize'],
|
||||
['max', 'max'],
|
||||
['maxSize', 'maxSize'],
|
||||
['itemCount', 'size'],
|
||||
['size', 'size'],
|
||||
['ttl', 'ttl'],
|
||||
]);
|
||||
propertyMap.forEach((lruProp, cacheProp) => {
|
||||
Object.defineProperty(cache, cacheProp, {
|
||||
|
||||
25
src/cache/ttl.js
vendored
25
src/cache/ttl.js
vendored
@@ -13,6 +13,23 @@ module.exports = function (opts) {
|
||||
cache.enabled = opts.hasOwnProperty('enabled') ? opts.enabled : true;
|
||||
const cacheSet = ttlCache.set;
|
||||
|
||||
// expose properties
|
||||
const propertyMap = new Map([
|
||||
['max', 'max'],
|
||||
['itemCount', 'size'],
|
||||
['size', 'size'],
|
||||
['ttl', 'ttl'],
|
||||
]);
|
||||
propertyMap.forEach((ttlProp, cacheProp) => {
|
||||
Object.defineProperty(cache, cacheProp, {
|
||||
get: function () {
|
||||
return ttlCache[ttlProp];
|
||||
},
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
});
|
||||
});
|
||||
|
||||
cache.set = function (key, value, ttl) {
|
||||
if (!cache.enabled) {
|
||||
return;
|
||||
@@ -90,5 +107,13 @@ module.exports = function (opts) {
|
||||
return unCachedKeys;
|
||||
};
|
||||
|
||||
cache.dump = function () {
|
||||
return Array.from(ttlCache.entries());
|
||||
};
|
||||
|
||||
cache.peek = function (key) {
|
||||
return ttlCache.get(key, { updateAgeOnGet: false });
|
||||
};
|
||||
|
||||
return cache;
|
||||
};
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
const cacheController = module.exports;
|
||||
|
||||
const utils = require('../../utils');
|
||||
const plugins = require('../../plugins');
|
||||
|
||||
cacheController.get = function (req, res) {
|
||||
cacheController.get = async function (req, res) {
|
||||
const postCache = require('../../posts/cache');
|
||||
const groupCache = require('../../groups').cache;
|
||||
const { objectCache } = require('../../database');
|
||||
@@ -23,29 +24,33 @@ cacheController.get = function (req, res) {
|
||||
misses: utils.addCommas(String(cache.misses)),
|
||||
hitRatio: ((cache.hits / (cache.hits + cache.misses) || 0)).toFixed(4),
|
||||
enabled: cache.enabled,
|
||||
ttl: cache.ttl,
|
||||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
postCache: getInfo(postCache),
|
||||
groupCache: getInfo(groupCache),
|
||||
localCache: getInfo(localCache),
|
||||
let caches = {
|
||||
post: postCache,
|
||||
group: groupCache,
|
||||
local: localCache,
|
||||
};
|
||||
|
||||
if (objectCache) {
|
||||
data.objectCache = getInfo(objectCache);
|
||||
caches.object = objectCache;
|
||||
}
|
||||
caches = await plugins.hooks.fire('filter:admin.cache.get', caches);
|
||||
for (const [key, value] of Object.entries(caches)) {
|
||||
caches[key] = getInfo(value);
|
||||
}
|
||||
|
||||
res.render('admin/advanced/cache', data);
|
||||
res.render('admin/advanced/cache', { caches });
|
||||
};
|
||||
|
||||
cacheController.dump = function (req, res, next) {
|
||||
const caches = {
|
||||
cacheController.dump = async function (req, res, next) {
|
||||
let caches = {
|
||||
post: require('../../posts/cache'),
|
||||
object: require('../../database').objectCache,
|
||||
group: require('../../groups').cache,
|
||||
local: require('../../cache'),
|
||||
};
|
||||
caches = await plugins.hooks.fire('filter:admin.cache.get', caches);
|
||||
if (!caches[req.query.name]) {
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -3,26 +3,30 @@
|
||||
const SocketCache = module.exports;
|
||||
|
||||
const db = require('../../database');
|
||||
const plugins = require('../../plugins');
|
||||
|
||||
SocketCache.clear = async function (socket, data) {
|
||||
if (data.name === 'post') {
|
||||
require('../../posts/cache').reset();
|
||||
} else if (data.name === 'object' && db.objectCache) {
|
||||
db.objectCache.reset();
|
||||
} else if (data.name === 'group') {
|
||||
require('../../groups').cache.reset();
|
||||
} else if (data.name === 'local') {
|
||||
require('../../cache').reset();
|
||||
}
|
||||
};
|
||||
|
||||
SocketCache.toggle = async function (socket, data) {
|
||||
const caches = {
|
||||
let caches = {
|
||||
post: require('../../posts/cache'),
|
||||
object: db.objectCache,
|
||||
group: require('../../groups').cache,
|
||||
local: require('../../cache'),
|
||||
};
|
||||
caches = await plugins.hooks.fire('filter:admin.cache.get', caches);
|
||||
if (!caches[data.name]) {
|
||||
return;
|
||||
}
|
||||
caches[data.name].reset();
|
||||
};
|
||||
|
||||
SocketCache.toggle = async function (socket, data) {
|
||||
let caches = {
|
||||
post: require('../../posts/cache'),
|
||||
object: db.objectCache,
|
||||
group: require('../../groups').cache,
|
||||
local: require('../../cache'),
|
||||
};
|
||||
caches = await plugins.hooks.fire('filter:admin.cache.get', caches);
|
||||
if (!caches[data.name]) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,118 +2,43 @@
|
||||
<div class="row post-cache">
|
||||
<div class="col-lg-12">
|
||||
<div class="row">
|
||||
{{{each caches}}}
|
||||
<div class="col-lg-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">[[admin/advanced/cache:post-cache]]</div>
|
||||
<div class="panel-heading">[[admin/advanced/cache:{@key}-cache]]</div>
|
||||
<div class="panel-body">
|
||||
<div class="checkbox" data-name="post">
|
||||
<div class="checkbox" data-name="{@key}">
|
||||
<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 caches.enabled}}}checked{{{end}}}>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<span>{postCache.length} / {postCache.maxSize}</span><br/>
|
||||
<span>{{{if ../length}}}{../length}{{{else}}}{../itemCount}{{{end}}} / {{{if ../max}}}{../max}{{{else}}}{../maxSize}{{{end}}}</span><br/>
|
||||
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="{postCache.percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {postCache.percentFull}%;">
|
||||
[[admin/advanced/cache:percent-full, {postCache.percentFull}]]
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="{../percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {../percentFull}%;">
|
||||
[[admin/advanced/cache:percent-full, {../percentFull}]]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Hits:</label> <span>{postCache.hits}</span><br/>
|
||||
<label>Misses:</label> <span>{postCache.misses}</span><br/>
|
||||
<label>Hit Ratio:</label> <span>{postCache.hitRatio}</span><br/>
|
||||
|
||||
<label>Hits:</label> <span>{../hits}</span><br/>
|
||||
<label>Misses:</label> <span>{../misses}</span><br/>
|
||||
<label>Hit Ratio:</label> <span>{../hitRatio}</span><br/>
|
||||
{{{if ../ttl}}}<label>TTL:</label> <span>{../ttl}</span></br>{{{end}}}
|
||||
{{{if (@key == "post")}}}
|
||||
<hr/>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="postCacheSize">[[admin/advanced/cache:post-cache-size]]</label>
|
||||
<input id="postCacheSize" type="text" class="form-control" value="" data-field="postCacheSize">
|
||||
</div>
|
||||
<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>
|
||||
|
||||
<!-- IF objectCache -->
|
||||
<div class="col-lg-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Object Cache</div>
|
||||
<div class="panel-body">
|
||||
<div class="checkbox" data-name="object">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||
<input class="mdl-switch__input" type="checkbox" {{{if objectCache.enabled}}}checked{{{end}}}>
|
||||
</label>
|
||||
</div>
|
||||
<span>{objectCache.itemCount} / {objectCache.max}</span><br/>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="{objectCache.percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {objectCache.percentFull}%;">
|
||||
[[admin/advanced/cache:percent-full, {objectCache.percentFull}]]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Hits:</label> <span>{objectCache.hits}</span><br/>
|
||||
<label>Misses:</label> <span>{objectCache.misses}</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-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>
|
||||
<!-- ENDIF objectCache -->
|
||||
|
||||
<div class="col-lg-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Group Cache</div>
|
||||
<div class="panel-body">
|
||||
<div class="checkbox" data-name="group">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||
<input class="mdl-switch__input" type="checkbox" {{{if groupCache.enabled}}}checked{{{end}}}>
|
||||
</label>
|
||||
</div>
|
||||
<span>{groupCache.itemCount} / {groupCache.max}</span><br/>
|
||||
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="{groupCache.percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {groupCache.percentFull}%;">
|
||||
[[admin/advanced/cache:percent-full, {groupCache.percentFull}]]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Hits:</label> <span>{groupCache.hits}</span><br/>
|
||||
<label>Misses:</label> <span>{groupCache.misses}</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-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 class="col-lg-3">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">Local Cache</div>
|
||||
<div class="panel-body">
|
||||
<div class="checkbox" data-name="local">
|
||||
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect">
|
||||
<input class="mdl-switch__input" type="checkbox" {{{if localCache.enabled}}}checked{{{end}}}>
|
||||
</label>
|
||||
</div>
|
||||
<span>{localCache.itemCount} / {localCache.max}</span><br/>
|
||||
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" aria-valuenow="{localCache.percentFull}" aria-valuemin="0" aria-valuemax="100" style="width: {localCache.percentFull}%;">
|
||||
[[admin/advanced/cache:percent-full, {localCache.percentFull}]]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label>Hits:</label> <span>{localCache.hits}</span><br/>
|
||||
<label>Misses:</label> <span>{localCache.misses}</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-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>
|
||||
{{{end}}}
|
||||
<a href="{config.relative_path}/api/admin/advanced/cache/dump?name={@key}" class="btn btn-sm btn-default"><i class="fa fa-download"></i></a>
|
||||
<a class="btn btn-sm btn-danger clear" data-name="{@key}"><i class="fa fa-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{{end}}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user