diff --git a/src/topics/delete.js b/src/topics/delete.js index 086609a667..2fd2364e26 100644 --- a/src/topics/delete.js +++ b/src/topics/delete.js @@ -96,8 +96,10 @@ module.exports = function (Topics) { t.tags = t.tags.map(tag => tag.value); }); - await deleteFromFollowersIgnorers(tidsToDelete); - + await Promise.all([ + deleteFromFollowersIgnorers(tidsToDelete), + deleteFromUserInboxes(tidsToDelete), + ]); const remoteTids = []; const localTids = []; @@ -163,6 +165,18 @@ module.exports = function (Topics) { await db.sortedSetRemoveBulk(bulkRemove); } + async function deleteFromUserInboxes(tids) { + const recipients = await db.getSortedSetsMembers(tids.map(tid => `tid:${tid}:recipients`)); + const bulkRemove = []; + tids.forEach((tid, index) => { + const tidRecipients = recipients[index]; + tidRecipients.forEach((uid) => { + bulkRemove.push([`uid:${uid}:inbox`, tid]); + }); + }); + await db.sortedSetRemoveBulk(bulkRemove); + } + async function deleteKeys(tids) { await db.deleteAll([ ...tids.map(tid => `tid:${tid}:followers`), @@ -171,6 +185,7 @@ module.exports = function (Topics) { ...tids.map(tid => `tid:${tid}:posts:votes`), ...tids.map(tid => `tid:${tid}:bookmarks`), ...tids.map(tid => `tid:${tid}:posters`), + ...tids.map(tid => `tid:${tid}:recipients`), ]); } diff --git a/src/upgrades/4.9.2/clean_tid_recipients_zsets.js b/src/upgrades/4.9.2/clean_tid_recipients_zsets.js new file mode 100644 index 0000000000..f750cb7dc2 --- /dev/null +++ b/src/upgrades/4.9.2/clean_tid_recipients_zsets.js @@ -0,0 +1,36 @@ +'use strict'; + +const db = require('../../database'); +const batch = require('../../batch'); + +module.exports = { + name: 'Delete pruned tids from user inboxes and delete tid::recipients sorted sets', + timestamp: Date.UTC(2026, 2, 5), + method: async function () { + const { progress } = this; + progress.total = await db.sortedSetCard('users:joindate'); + + await batch.processSortedSet('users:joindate', async (uids) => { + const userInboxes = await db.getSortedSetsMembers(uids.map(uid => `uid:${uid}:inbox`)); + const exists = await Promise.all( + userInboxes.map(userTids => db.exists(userTids.map(tid => `topic:${tid}`))) + ); + + const bulkRemove = []; + const deleteTids = new Set(); + uids.forEach((uid, index) => { + const userTids = userInboxes[index]; + userTids.forEach((tid, tidIndex) => { + if (!exists[index][tidIndex]) { + bulkRemove.push([`uid:${uid}:inbox`, tid]); + deleteTids.add(tid); + } + }); + }); + await db.deleteAll(Array.from(deleteTids).map(tid => `tid:${tid}:recipients`)); + progress.incr(uids.length); + }, { + batch: 500, + }); + }, +};