perf: closes #13145, reduce calls in actors.prune

instead of deleting 18k users everyday delete max 500 every 30mins like notifications.prune

refactor getLocalFollowCounts so it works with an array of actors

dont make dbcalls for uids that dont exist
This commit is contained in:
Barış Soner Uşaklı
2025-02-11 10:39:24 -05:00
committed by Barış Soner Uşaklı
parent 224910b133
commit d590c2afcf
2 changed files with 14 additions and 13 deletions

View File

@@ -298,7 +298,7 @@ Actors.prune = async () => {
const days = parseInt(meta.config.activitypubUserPruneDays, 10); const days = parseInt(meta.config.activitypubUserPruneDays, 10);
const timestamp = Date.now() - (1000 * 60 * 60 * 24 * days); const timestamp = Date.now() - (1000 * 60 * 60 * 24 * days);
const uids = await db.getSortedSetRangeByScore('usersRemote:lastCrawled', 0, -1, '-inf', timestamp); const uids = await db.getSortedSetRangeByScore('usersRemote:lastCrawled', 0, 500, '-inf', timestamp);
if (!uids.length) { if (!uids.length) {
winston.info('[actors/prune] No remote users to prune, all done.'); winston.info('[actors/prune] No remote users to prune, all done.');
return; return;
@@ -309,18 +309,19 @@ Actors.prune = async () => {
await batch.processArray(uids, async (uids) => { await batch.processArray(uids, async (uids) => {
const exists = await db.exists(uids.map(uid => `userRemote:${uid}`)); const exists = await db.exists(uids.map(uid => `userRemote:${uid}`));
const [postCounts, roomCounts] = await Promise.all([
db.sortedSetsCard(uids.map(uid => `uid:${uid}:posts`)),
db.sortedSetsCard(uids.map(uid => `uid:${uid}:chat:rooms`)),
]);
await Promise.all(uids.map(async (uid, idx) => {
if (!exists[idx]) {
// id in zset but not asserted, handle and return early
await db.sortedSetRemove('usersRemote:lastCrawled', uid);
return;
}
const { followers, following } = await Actors.getLocalFollowCounts(uid); const uidsThatExist = uids.filter((uid, idx) => exists[idx]);
const uidsThatDontExist = uids.filter((uid, idx) => !exists[idx]);
await db.sortedSetRemove('usersRemote:lastCrawled', uidsThatDontExist);
const [postCounts, roomCounts, followCounts] = await Promise.all([
db.sortedSetsCard(uidsThatExist.map(uid => `uid:${uid}:posts`)),
db.sortedSetsCard(uidsThatExist.map(uid => `uid:${uid}:chat:rooms`)),
Actors.getLocalFollowCounts(uidsThatExist),
]);
await Promise.all(uidsThatExist.map(async (uid, idx) => {
const { followers, following } = followCounts[idx];
const postCount = postCounts[idx]; const postCount = postCounts[idx];
const roomCount = roomCounts[idx]; const roomCount = roomCounts[idx];
if ([postCount, roomCount, followers, following].every(metric => metric < 1)) { if ([postCount, roomCount, followers, following].every(metric => metric < 1)) {

View File

@@ -66,7 +66,7 @@ ActivityPub.startJobs = () => {
} }
}, null, true, null, null, false); // change last argument to true for debugging }, null, true, null, null, false); // change last argument to true for debugging
new CronJob('0 1 * * *', async () => { new CronJob('*/30 * * * *', async () => {
try { try {
await ActivityPub.actors.prune(); await ActivityPub.actors.prune();
} catch (err) { } catch (err) {