hippofish/packages/backend/src/misc/skipped-instances.ts

64 lines
2.1 KiB
TypeScript
Raw Normal View History

2023-01-13 05:40:33 +01:00
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.
2023-01-13 05:40:33 +01:00
*
* @param hosts array of punycoded instance hosts
* @returns array of punycoed instance hosts that should be skipped (subset of hosts parameter)
*/
2023-01-13 05:40:33 +01:00
export async function skippedInstances(
hosts: Instance["host"][],
): Promise<Instance["host"][]> {
// first check for blocked instances since that info may already be in memory
2022-12-24 20:39:54 +01:00
const meta = await fetchMeta();
2023-01-13 05:40:33 +01:00
const shouldSkip = await Promise.all(
hosts.map((host) => shouldBlockInstance(host, meta)),
);
2022-12-24 20:39:54 +01:00
const skipped = hosts.filter((_, i) => shouldSkip[i]);
2023-01-13 05:40:33 +01:00
// if possible return early and skip accessing the database
2023-01-13 05:40:33 +01:00
if (skipped.length === hosts.length) return hosts;
const deadTime = new Date(Date.now() - deadThreshold);
return skipped.concat(
2023-01-13 05:40:33 +01:00
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
2023-01-13 05:40:33 +01:00
hosts: hosts.filter((host) => !skipped.includes(host)),
})
2023-01-13 05:40:33 +01:00
.andWhere(
new Brackets((qb) => {
qb.where("instance.isSuspended");
}),
)
.select("host")
2023-01-03 18:12:26 +01:00
.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
*/
2023-01-13 05:40:33 +01:00
export async function shouldSkipInstance(
host: Instance["host"],
): Promise<boolean> {
const skipped = await skippedInstances([host]);
return skipped.length > 0;
}