mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
perf: only load thumbs for topics that actually have thumbs
This commit is contained in:
@@ -82,7 +82,7 @@ Topics.getTopicsByTids = async function (tids, options) {
|
|||||||
user.getMultipleUserSettings(uids),
|
user.getMultipleUserSettings(uids),
|
||||||
categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'backgroundImage', 'imageClass', 'bgColor', 'color', 'disabled']),
|
categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'backgroundImage', 'imageClass', 'bgColor', 'color', 'disabled']),
|
||||||
loadGuestHandles(),
|
loadGuestHandles(),
|
||||||
Topics.thumbs.get(tids),
|
Topics.thumbs.load(topics),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
users.forEach((userObj, idx) => {
|
users.forEach((userObj, idx) => {
|
||||||
@@ -167,11 +167,11 @@ Topics.getTopicWithPosts = async function (topicData, set, uid, start, stop, rev
|
|||||||
getDeleter(topicData),
|
getDeleter(topicData),
|
||||||
getMerger(topicData),
|
getMerger(topicData),
|
||||||
getRelated(topicData, uid),
|
getRelated(topicData, uid),
|
||||||
Topics.thumbs.get(topicData.tid),
|
Topics.thumbs.load([topicData]),
|
||||||
Topics.events.get(topicData.tid),
|
Topics.events.get(topicData.tid),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
topicData.thumbs = thumbs;
|
topicData.thumbs = thumbs[0];
|
||||||
topicData.posts = posts;
|
topicData.posts = posts;
|
||||||
topicData.events = events;
|
topicData.events = events;
|
||||||
topicData.category = category;
|
topicData.category = category;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const _ = require('lodash');
|
||||||
const nconf = require('nconf');
|
const nconf = require('nconf');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const validator = require('validator');
|
const validator = require('validator');
|
||||||
@@ -19,6 +20,14 @@ Thumbs.exists = async function (tid, path) {
|
|||||||
return db.isSortedSetMember(`topic:${tid}:thumbs`, path);
|
return db.isSortedSetMember(`topic:${tid}:thumbs`, path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Thumbs.load = async function (topicData) {
|
||||||
|
const topicsWithThumbs = topicData.filter(t => parseInt(t.numThumbs, 10) > 0);
|
||||||
|
const tidsWithThumbs = topicsWithThumbs.map(t => t.tid);
|
||||||
|
const thumbs = await Thumbs.get(tidsWithThumbs);
|
||||||
|
const tidToThumbs = _.zipObject(tidsWithThumbs, thumbs);
|
||||||
|
return topicData.map(t => tidToThumbs[t.tid] || []);
|
||||||
|
};
|
||||||
|
|
||||||
Thumbs.get = async function (tids) {
|
Thumbs.get = async function (tids) {
|
||||||
// Allow singular or plural usage
|
// Allow singular or plural usage
|
||||||
let singular = false;
|
let singular = false;
|
||||||
@@ -27,14 +36,14 @@ Thumbs.get = async function (tids) {
|
|||||||
singular = true;
|
singular = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!meta.config.allowTopicsThumbnail) {
|
if (!meta.config.allowTopicsThumbnail || !tids.length) {
|
||||||
return singular ? [] : tids.map(() => []);
|
return singular ? [] : tids.map(() => []);
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasTimestampPrefix = /^\d+-/;
|
const hasTimestampPrefix = /^\d+-/;
|
||||||
const upload_url = nconf.get('relative_path') + nconf.get('upload_url');
|
const upload_url = nconf.get('relative_path') + nconf.get('upload_url');
|
||||||
const sets = tids.map(tid => `${validator.isUUID(String(tid)) ? 'draft' : 'topic'}:${tid}:thumbs`);
|
const sets = tids.map(tid => `${validator.isUUID(String(tid)) ? 'draft' : 'topic'}:${tid}:thumbs`);
|
||||||
const thumbs = await Promise.all(sets.map(set => getThumbs(set)));
|
const thumbs = await Promise.all(sets.map(getThumbs));
|
||||||
let response = thumbs.map((thumbSet, idx) => thumbSet.map(thumb => ({
|
let response = thumbs.map((thumbSet, idx) => thumbSet.map(thumb => ({
|
||||||
id: tids[idx],
|
id: tids[idx],
|
||||||
name: (() => {
|
name: (() => {
|
||||||
@@ -69,13 +78,15 @@ Thumbs.associate = async function ({ id, path: relativePath, url }) {
|
|||||||
if (relativePath) {
|
if (relativePath) {
|
||||||
value = value.replace(nconf.get('upload_path'), '');
|
value = value.replace(nconf.get('upload_path'), '');
|
||||||
}
|
}
|
||||||
|
const topics = require('.');
|
||||||
await db.sortedSetAdd(set, numThumbs, value);
|
await db.sortedSetAdd(set, numThumbs, value);
|
||||||
|
if (!isDraft) {
|
||||||
|
await topics.setTopicField(id, 'numThumbs', numThumbs);
|
||||||
|
}
|
||||||
cache.del(set);
|
cache.del(set);
|
||||||
|
|
||||||
// Associate thumbnails with the main pid (only on local upload)
|
// Associate thumbnails with the main pid (only on local upload)
|
||||||
if (!isDraft && relativePath) {
|
if (!isDraft && relativePath) {
|
||||||
const topics = require('.');
|
|
||||||
const mainPid = (await topics.getMainPids([id]))[0];
|
const mainPid = (await topics.getMainPids([id]))[0];
|
||||||
posts.uploads.associate(mainPid, relativePath.replace('/files/', ''));
|
posts.uploads.associate(mainPid, relativePath.replace('/files/', ''));
|
||||||
}
|
}
|
||||||
@@ -110,6 +121,10 @@ Thumbs.delete = async function (id, relativePath) {
|
|||||||
// Dissociate thumbnails with the main pid
|
// Dissociate thumbnails with the main pid
|
||||||
if (!isDraft) {
|
if (!isDraft) {
|
||||||
const topics = require('.');
|
const topics = require('.');
|
||||||
|
const numThumbs = await db.sortedSetCard(set);
|
||||||
|
if (!numThumbs) {
|
||||||
|
await db.deleteObjectField('topic:' + id, 'numThumbs');
|
||||||
|
}
|
||||||
const mainPid = (await topics.getMainPids([id]))[0];
|
const mainPid = (await topics.getMainPids([id]))[0];
|
||||||
posts.uploads.dissociate(mainPid, relativePath.replace('/files/', ''));
|
posts.uploads.dissociate(mainPid, relativePath.replace('/files/', ''));
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/upgrades/1.17.0/topic_thumb_count.js
Normal file
29
src/upgrades/1.17.0/topic_thumb_count.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const _ = require('lodash');
|
||||||
|
const db = require('../../database');
|
||||||
|
const batch = require('../../batch');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'Store number of thumbs a topic has in the topic object',
|
||||||
|
timestamp: Date.UTC(2021, 1, 7),
|
||||||
|
method: async function () {
|
||||||
|
const progress = this.progress;
|
||||||
|
|
||||||
|
await batch.processSortedSet('topics:tid', async function (tids) {
|
||||||
|
const keys = tids.map(tid => 'topic:' + tid + ':thumbs');
|
||||||
|
const counts = await db.sortedSetsCard(keys);
|
||||||
|
const tidToCount = _.zip(tids, counts);
|
||||||
|
const tidsWithThumbs = tids.filter((t, i) => counts[i] > 0);
|
||||||
|
await db.setObjectBulk(
|
||||||
|
tidsWithThumbs.map(tid => 'topic:' + tid),
|
||||||
|
tidsWithThumbs.map(tid => ({ numThumbs: tidToCount[tid] }))
|
||||||
|
);
|
||||||
|
|
||||||
|
progress.incr(tids.length);
|
||||||
|
}, {
|
||||||
|
batch: 500,
|
||||||
|
progress: progress,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user