server: update instance metadata in separate job

Previously, the deliver and inbox queue jobs would also take care of
updating the instance metadata. On a low resource server like mine,
the deliver queue is often the "critical path" and handling this
there is not a good idea.

Instead, this is handled in a separate job and with a slight delay,
to not interfere with bulk delivery jobs.
This commit is contained in:
Johann150 2024-08-30 01:31:02 +02:00
parent 6ce067af56
commit 886e21e2dd
Signed by: Johann150
GPG key ID: 9EE6577A2A06F8F1
4 changed files with 35 additions and 2 deletions

View file

@ -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() { export default function() {
deliverQueue.process(config.deliverJobConcurrency, processDeliver); deliverQueue.process(config.deliverJobConcurrency, processDeliver);
inboxQueue.process(config.inboxJobConcurrency, processInbox); inboxQueue.process(config.inboxJobConcurrency, processInbox);

View file

@ -3,12 +3,14 @@ import { tickCharts } from './tick-charts.js';
import { resyncCharts } from './resync-charts.js'; import { resyncCharts } from './resync-charts.js';
import { cleanCharts } from './clean-charts.js'; import { cleanCharts } from './clean-charts.js';
import { checkExpired } from './check-expired.js'; import { checkExpired } from './check-expired.js';
import { updateInstance } from './update-instance.js';
const jobs = { const jobs = {
tickCharts, tickCharts,
resyncCharts, resyncCharts,
cleanCharts, cleanCharts,
checkExpired, checkExpired,
updateInstance,
} as Record<string, Bull.ProcessCallbackFunction<Record<string, unknown>> | Bull.ProcessPromiseFunction<Record<string, unknown>>>; } as Record<string, Bull.ProcessCallbackFunction<Record<string, unknown>> | Bull.ProcessPromiseFunction<Record<string, unknown>>>;
export default function(dbQueue: Bull.Queue<Record<string, unknown>>) { export default function(dbQueue: Bull.Queue<Record<string, unknown>>) {

View file

@ -0,0 +1,8 @@
import Bull from 'bull';
import { fetchInstanceMetadata } from '@/services/fetch-instance-metadata.js';
export async function updateInstance(job: Bull.Job<Record<string, unknown>>, done: any): Promise<void> {
await fetchInstanceMetadata({ host: job.data.host }, true);
done();
}

View file

@ -7,6 +7,7 @@ import { getJson, getHtml, getAgentByUrl } from '@/misc/fetch.js';
import { Instance } from '@/models/entities/instance.js'; import { Instance } from '@/models/entities/instance.js';
import { Instances } from '@/models/index.js'; import { Instances } from '@/models/index.js';
import { getFetchInstanceMetadataLock } from '@/misc/app-lock.js'; import { getFetchInstanceMetadataLock } from '@/misc/app-lock.js';
import { createUpdateInstanceJob } from '@/queue/index.js';
import Logger from './logger.js'; import Logger from './logger.js';
const logger = new Logger('metadata'); const logger = new Logger('metadata');
@ -16,8 +17,14 @@ export async function fetchInstanceMetadata(instance: Instance, force = false):
if (!force) { if (!force) {
const _instance = await Instances.findOneBy({ host: instance.host }); const _instance = await Instances.findOneBy({ host: instance.host });
const now = Date.now(); if (_instance && _instance.infoUpdatedAt) {
if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < DAY)) { 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(); unlock();
return; return;
} }