Improve server performance

This commit is contained in:
syuilo 2021-03-18 10:49:14 +09:00
parent d3c8368b0c
commit 8aa089178a
4 changed files with 54 additions and 10 deletions

25
src/misc/cache.ts Normal file
View file

@ -0,0 +1,25 @@
export class Cache<T> {
private cache: Map<string | null, { date: number; value: T; }>;
private lifetime: number;
constructor(lifetime: Cache<never>['lifetime']) {
this.lifetime = lifetime;
}
public set(key: string | null, value: T):void {
this.cache.set(key, {
date: Date.now(),
value
});
}
public get(key: string | null): T | null {
const cached = this.cache.get(key);
if (cached == null) return null;
if ((Date.now() - cached.date) > this.lifetime) {
this.cache.delete(key);
return null;
}
return cached.value;
}
}

View file

@ -7,11 +7,15 @@ import { instanceChart } from '../../services/chart';
import { fetchInstanceMetadata } from '../../services/fetch-instance-metadata'; import { fetchInstanceMetadata } from '../../services/fetch-instance-metadata';
import { fetchMeta } from '../../misc/fetch-meta'; import { fetchMeta } from '../../misc/fetch-meta';
import { toPuny } from '../../misc/convert-host'; import { toPuny } from '../../misc/convert-host';
import { Cache } from '../../misc/cache';
import { Instance } from '../../models/entities/instance';
const logger = new Logger('deliver'); const logger = new Logger('deliver');
let latest: string | null = null; let latest: string | null = null;
const suspendedHostsCache = new Cache<Instance[]>(1000 * 60 * 60);
export default async (job: Bull.Job) => { export default async (job: Bull.Job) => {
const { host } = new URL(job.data.to); const { host } = new URL(job.data.to);
@ -22,12 +26,15 @@ export default async (job: Bull.Job) => {
} }
// isSuspendedなら中断 // isSuspendedなら中断
const suspendedHosts = await Instances.find({ let suspendedHosts = suspendedHostsCache.get(null);
where: { if (suspendedHosts == null) {
isSuspended: true suspendedHosts = await Instances.find({
}, where: {
cache: 60 * 1000 isSuspended: true
}); },
});
suspendedHostsCache.set(null, suspendedHosts);
}
if (suspendedHosts.map(x => x.host).includes(toPuny(host))) { if (suspendedHosts.map(x => x.host).includes(toPuny(host))) {
return 'skip (suspended)'; return 'skip (suspended)';
} }

View file

@ -2,8 +2,11 @@ import isNativeToken from './common/is-native-token';
import { User } from '../../models/entities/user'; import { User } from '../../models/entities/user';
import { Users, AccessTokens, Apps } from '../../models'; import { Users, AccessTokens, Apps } from '../../models';
import { AccessToken } from '../../models/entities/access-token'; import { AccessToken } from '../../models/entities/access-token';
import { Cache } from '../../misc/cache';
const cache = {} as Record<string, User>; // TODO: TypeORMのカスタムキャッシュプロバイダを使っても良いかも
// ref. https://github.com/typeorm/typeorm/blob/master/docs/caching.md
const cache = new Cache<User>(1000 * 60 * 60);
export default async (token: string): Promise<[User | null | undefined, AccessToken | null | undefined]> => { export default async (token: string): Promise<[User | null | undefined, AccessToken | null | undefined]> => {
if (token == null) { if (token == null) {
@ -11,8 +14,9 @@ export default async (token: string): Promise<[User | null | undefined, AccessTo
} }
if (isNativeToken(token)) { if (isNativeToken(token)) {
if (cache[token]) { // TODO: キャッシュされてから一定時間経過していたら破棄する const cached = cache.get(token);
return [cache[token], null]; if (cached) {
return [cached, null];
} }
// Fetch user // Fetch user
@ -23,7 +27,7 @@ export default async (token: string): Promise<[User | null | undefined, AccessTo
throw new Error('user not found'); throw new Error('user not found');
} }
cache[token] = user; cache.set(token, user);
return [user, null]; return [user, null];
} else { } else {

View file

@ -3,10 +3,16 @@ import { Instances } from '../models';
import { federationChart } from './chart'; import { federationChart } from './chart';
import { genId } from '../misc/gen-id'; import { genId } from '../misc/gen-id';
import { toPuny } from '../misc/convert-host'; import { toPuny } from '../misc/convert-host';
import { Cache } from '../misc/cache';
const cache = new Cache<Instance>(1000 * 60 * 60);
export async function registerOrFetchInstanceDoc(host: string): Promise<Instance> { export async function registerOrFetchInstanceDoc(host: string): Promise<Instance> {
host = toPuny(host); host = toPuny(host);
const cached = cache.get(host);
if (cached) return cached;
const index = await Instances.findOne({ host }); const index = await Instances.findOne({ host });
if (index == null) { if (index == null) {
@ -19,8 +25,10 @@ export async function registerOrFetchInstanceDoc(host: string): Promise<Instance
federationChart.update(true); federationChart.update(true);
cache.set(host, i);
return i; return i;
} else { } else {
cache.set(host, index);
return index; return index;
} }
} }