From 5a691f7e987d2ab13a693835b6bbdd80a17c8f55 Mon Sep 17 00:00:00 2001 From: Johann150 Date: Sat, 29 Oct 2022 03:13:22 +0200 Subject: [PATCH] server: avoid adding suspended instances to deliver queue This should reduce the performance hit when adding large numbers of instances to the deliver queue by making the check for suspended and dead instances a bulk operation. Changelog: Changed Reviewed-on: https://akkoma.dev/FoundKeyGang/FoundKey/pulls/215 --- CALCKEY.md | 6 ++-- .../backend/src/queue/processors/deliver.ts | 35 +++---------------- .../src/remote/activitypub/deliver-manager.ts | 20 ++++++++--- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/CALCKEY.md b/CALCKEY.md index 4ee5dfc454..990908ca82 100644 --- a/CALCKEY.md +++ b/CALCKEY.md @@ -121,6 +121,6 @@ - b0fdedb264db87575063abed45e52ad71ce4a6af: fix lints in folder.vue - 6fed87f85d132304eb84b0a59b84dce299a1822f: fix pagination.vue lints - Tosti's security fixes - - 384e8c49b738f576ba8843296de6cebf01c1b247: server: allow to like own gallery posts - - 4c5aa9e53887cca5561fcec6ab0754e018f589a5: server: allow to like own pages - - 923c93da1228458dd65be47483c198a1a9191bcf: use await for notes.countBy + - 384e8c49b738f576ba8843296de6cebf01c1b247: server: allow to like own gallery posts + - 4c5aa9e53887cca5561fcec6ab0754e018f589a5: server: allow to like own pages + - 923c93da1228458dd65be47483c198a1a9191bcf: use await for notes.countBy diff --git a/packages/backend/src/queue/processors/deliver.ts b/packages/backend/src/queue/processors/deliver.ts index df070d1de5..df8dbb23eb 100644 --- a/packages/backend/src/queue/processors/deliver.ts +++ b/packages/backend/src/queue/processors/deliver.ts @@ -1,50 +1,25 @@ import { URL } from 'node:url'; -import Bull from 'bull'; import request from '@/remote/activitypub/request.js'; import { registerOrFetchInstanceDoc } from '@/services/register-or-fetch-instance-doc.js'; import Logger from '@/services/logger.js'; import { Instances } from '@/models/index.js'; import { apRequestChart, federationChart, instanceChart } from '@/services/chart/index.js'; import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata.js'; -import { fetchMeta } from '@/misc/fetch-meta.js'; import { toPuny } from '@/misc/convert-host.js'; -import { Cache } from '@/misc/cache.js'; -import { Instance } from '@/models/entities/instance.js'; -import { DeliverJobData } from '../types.js'; import { StatusError } from '@/misc/fetch.js'; +import { shouldSkipInstance } from '@/misc/skipped-instances.js'; +import type { DeliverJobData } from '@/queue/types.js'; +import type Bull from 'bull'; const logger = new Logger('deliver'); let latest: string | null = null; -const suspendedHostsCache = new Cache(1000 * 60 * 60); - export default async (job: Bull.Job) => { const { host } = new URL(job.data.to); + const puny = toPuny(host); - // ブロックしてたら中断 - const meta = await fetchMeta(); - if (meta.blockedHosts.includes(toPuny(host))) { - return 'skip (blocked)'; - } - - if (meta.privateMode && !meta.allowedHosts.includes(toPuny(host))) { - return 'skip (not allowed)'; - } - - // isSuspendedなら中断 - let suspendedHosts = suspendedHostsCache.get(null); - if (suspendedHosts == null) { - suspendedHosts = await Instances.find({ - where: { - isSuspended: true, - }, - }); - suspendedHostsCache.set(null, suspendedHosts); - } - if (suspendedHosts.map(x => x.host).includes(toPuny(host))) { - return 'skip (suspended)'; - } + if (await shouldSkipInstance(puny)) return 'skip'; try { if (latest !== (latest = JSON.stringify(job.data.content, null, 2))) { diff --git a/packages/backend/src/remote/activitypub/deliver-manager.ts b/packages/backend/src/remote/activitypub/deliver-manager.ts index 4c1999e4cb..1bcdcdfdb2 100644 --- a/packages/backend/src/remote/activitypub/deliver-manager.ts +++ b/packages/backend/src/remote/activitypub/deliver-manager.ts @@ -1,7 +1,8 @@ -import { Users, Followings } from '@/models/index.js'; -import { ILocalUser, IRemoteUser, User } from '@/models/entities/user.js'; -import { deliver } from '@/queue/index.js'; import { IsNull, Not } from 'typeorm'; +import { Users, Followings } from '@/models/index.js'; +import type { ILocalUser, IRemoteUser, User } from '@/models/entities/user.js'; +import { deliver } from '@/queue/index.js'; +import { skippedInstances } from '@/misc/skipped-instances.js'; //#region types interface IRecipe { @@ -117,10 +118,21 @@ export default class DeliverManager { // check that they actually have an inbox && recipe.to.inbox != null, ) - .forEach(recipe => inboxes.add(recipe.to.inbox!)); + .forEach(recipe => inboxes.add(recipe.to.inbox!)); + + const instancesToSkip = await skippedInstances( + // get (unique) list of hosts + Array.from(new Set( + Array.from(inboxes) + .map(inbox => new URL(inbox).host), + )), + ); // deliver for (const inbox of inboxes) { + // skip instances as indicated + if (instancesToSkip.includes(new URL(inbox).host)) continue; + deliver(this.actor, this.activity, inbox); } }