diff --git a/packages/backend/src/queue/index.ts b/packages/backend/src/queue/index.ts index 95657f99c..9ebec7e98 100644 --- a/packages/backend/src/queue/index.ts +++ b/packages/backend/src/queue/index.ts @@ -310,6 +310,22 @@ export function webhookDeliver(webhook: Webhook, type: typeof webhookEventTypes[ }); } +export function createUpdateInstanceJob(host: string) { + return systemQueue.add( + 'updateInstance', + { host }, + { + delay: 5 * MINUTE, + // The docs say that trying to add a job with an ID that already exists will + // not actually add the job. This is useful to not duplicate jobs when parallel + // jobs request an update. + jobId: host, + removeOnComplete: true, + removeOnFail: 10, + } + ); +} + export default function() { deliverQueue.process(config.deliverJobConcurrency, processDeliver); inboxQueue.process(config.inboxJobConcurrency, processInbox); diff --git a/packages/backend/src/queue/processors/system/index.ts b/packages/backend/src/queue/processors/system/index.ts index 3651f8790..ffd3a77c5 100644 --- a/packages/backend/src/queue/processors/system/index.ts +++ b/packages/backend/src/queue/processors/system/index.ts @@ -3,12 +3,14 @@ import { tickCharts } from './tick-charts.js'; import { resyncCharts } from './resync-charts.js'; import { cleanCharts } from './clean-charts.js'; import { checkExpired } from './check-expired.js'; +import { updateInstance } from './update-instance.js'; const jobs = { tickCharts, resyncCharts, cleanCharts, checkExpired, + updateInstance, } as Record> | Bull.ProcessPromiseFunction>>; export default function(dbQueue: Bull.Queue>) { diff --git a/packages/backend/src/queue/processors/system/update-instance.ts b/packages/backend/src/queue/processors/system/update-instance.ts new file mode 100644 index 000000000..657e0bf67 --- /dev/null +++ b/packages/backend/src/queue/processors/system/update-instance.ts @@ -0,0 +1,8 @@ +import Bull from 'bull'; +import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata.js'; + +export async function updateInstance(job: Bull.Job>, done: any): Promise { + await fetchInstanceMetadata({ host: job.data.host }, true); + + done(); +} diff --git a/packages/backend/src/services/fetch-instance-metadata.ts b/packages/backend/src/services/fetch-instance-metadata.ts index aee96172d..3b3c2d7aa 100644 --- a/packages/backend/src/services/fetch-instance-metadata.ts +++ b/packages/backend/src/services/fetch-instance-metadata.ts @@ -7,6 +7,7 @@ import { getJson, getHtml, getAgentByUrl } from '@/misc/fetch.js'; import { Instance } from '@/models/entities/instance.js'; import { Instances } from '@/models/index.js'; import { getFetchInstanceMetadataLock } from '@/misc/app-lock.js'; +import { createUpdateInstanceJob } from '@/queue/index.js'; import Logger from './logger.js'; const logger = new Logger('metadata'); @@ -16,8 +17,14 @@ export async function fetchInstanceMetadata(instance: Instance, force = false): if (!force) { const _instance = await Instances.findOneBy({ host: instance.host }); - const now = Date.now(); - if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < DAY)) { + if (_instance && _instance.infoUpdatedAt) { + const threshold = Date.now() - _instance.infoUpdatedAt.getTime(); + if (threshold > DAY) { + // queue a job to deal with it later + createUpdateInstanceJob(instance.host); + } + // if the instance is already known and force is not specified, + // never update the data in the same thread unlock(); return; }