import { Brackets } from 'typeorm'; import { fetchMeta } from '@/misc/fetch-meta.js'; import { Instances } from '@/models/index.js'; import type { Instance } from '@/models/entities/instance.js'; import { DAY } from '@/const.js'; import { shouldBlockInstance } from './should-block-instance.js'; // Threshold from last contact after which an instance will be considered // "dead" and should no longer get activities delivered to it. const deadThreshold = 7 * DAY; /** * Returns the subset of hosts which should be skipped. * * @param hosts array of punycoded instance hosts * @returns array of punycoed instance hosts that should be skipped (subset of hosts parameter) */ export async function skippedInstances(hosts: Instance['host'][]): Promise { // first check for blocked instances since that info may already be in memory const meta = await fetchMeta(); const shouldSkip = await Promise.all(hosts.map(host => shouldBlockInstance(host, meta))); const skipped = hosts.filter((_, i) => shouldSkip[i]); // if possible return early and skip accessing the database if (skipped.length === hosts.length) return hosts; const deadTime = new Date(Date.now() - deadThreshold); return skipped.concat( await Instances.createQueryBuilder('instance') .where('instance.host in (:...hosts)', { // don't check hosts again that we already know are suspended // also avoids adding duplicates to the list hosts: hosts.filter(host => !skipped.includes(host)), }) .andWhere(new Brackets(qb => { qb .where('instance.isSuspended'); })) .select('host') .getRawMany(), ); } /** * Returns whether a specific host (punycoded) should be skipped. * Convenience wrapper around skippedInstances which should only be used if there is a single host to check. * If you have multiple hosts, consider using skippedInstances instead to do a bulk check. * * @param host punycoded instance host * @returns whether the given host should be skipped */ export async function shouldSkipInstance(host: Instance['host']): Promise { const skipped = await skippedInstances([host]); return skipped.length > 0; }