From 8aa089178a54559cbc4e4fe84a618fc7535f178c Mon Sep 17 00:00:00 2001 From: syuilo Date: Thu, 18 Mar 2021 10:49:14 +0900 Subject: [PATCH] Improve server performance --- src/misc/cache.ts | 25 +++++++++++++++++++ src/queue/processors/deliver.ts | 19 +++++++++----- src/server/api/authenticate.ts | 12 ++++++--- .../register-or-fetch-instance-doc.ts | 8 ++++++ 4 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 src/misc/cache.ts diff --git a/src/misc/cache.ts b/src/misc/cache.ts new file mode 100644 index 0000000000..356a3de7b9 --- /dev/null +++ b/src/misc/cache.ts @@ -0,0 +1,25 @@ +export class Cache { + private cache: Map; + private lifetime: number; + + constructor(lifetime: Cache['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; + } +} diff --git a/src/queue/processors/deliver.ts b/src/queue/processors/deliver.ts index cb7587ef81..a8b4ed4fe3 100644 --- a/src/queue/processors/deliver.ts +++ b/src/queue/processors/deliver.ts @@ -7,11 +7,15 @@ import { instanceChart } from '../../services/chart'; import { fetchInstanceMetadata } from '../../services/fetch-instance-metadata'; import { fetchMeta } from '../../misc/fetch-meta'; import { toPuny } from '../../misc/convert-host'; +import { Cache } from '../../misc/cache'; +import { Instance } from '../../models/entities/instance'; const logger = new Logger('deliver'); let latest: string | null = null; +const suspendedHostsCache = new Cache(1000 * 60 * 60); + export default async (job: Bull.Job) => { const { host } = new URL(job.data.to); @@ -22,12 +26,15 @@ export default async (job: Bull.Job) => { } // isSuspendedなら中断 - const suspendedHosts = await Instances.find({ - where: { - isSuspended: true - }, - cache: 60 * 1000 - }); + let suspendedHosts = suspendedHostsCache.get(null); + if (suspendedHosts == null) { + suspendedHosts = await Instances.find({ + where: { + isSuspended: true + }, + }); + suspendedHostsCache.set(null, suspendedHosts); + } if (suspendedHosts.map(x => x.host).includes(toPuny(host))) { return 'skip (suspended)'; } diff --git a/src/server/api/authenticate.ts b/src/server/api/authenticate.ts index 7404c477fd..9c9ef74352 100644 --- a/src/server/api/authenticate.ts +++ b/src/server/api/authenticate.ts @@ -2,8 +2,11 @@ import isNativeToken from './common/is-native-token'; import { User } from '../../models/entities/user'; import { Users, AccessTokens, Apps } from '../../models'; import { AccessToken } from '../../models/entities/access-token'; +import { Cache } from '../../misc/cache'; -const cache = {} as Record; +// TODO: TypeORMのカスタムキャッシュプロバイダを使っても良いかも +// ref. https://github.com/typeorm/typeorm/blob/master/docs/caching.md +const cache = new Cache(1000 * 60 * 60); export default async (token: string): Promise<[User | null | undefined, AccessToken | null | undefined]> => { if (token == null) { @@ -11,8 +14,9 @@ export default async (token: string): Promise<[User | null | undefined, AccessTo } if (isNativeToken(token)) { - if (cache[token]) { // TODO: キャッシュされてから一定時間経過していたら破棄する - return [cache[token], null]; + const cached = cache.get(token); + if (cached) { + return [cached, null]; } // Fetch user @@ -23,7 +27,7 @@ export default async (token: string): Promise<[User | null | undefined, AccessTo throw new Error('user not found'); } - cache[token] = user; + cache.set(token, user); return [user, null]; } else { diff --git a/src/services/register-or-fetch-instance-doc.ts b/src/services/register-or-fetch-instance-doc.ts index 3501e20de1..2c39502288 100644 --- a/src/services/register-or-fetch-instance-doc.ts +++ b/src/services/register-or-fetch-instance-doc.ts @@ -3,10 +3,16 @@ import { Instances } from '../models'; import { federationChart } from './chart'; import { genId } from '../misc/gen-id'; import { toPuny } from '../misc/convert-host'; +import { Cache } from '../misc/cache'; + +const cache = new Cache(1000 * 60 * 60); export async function registerOrFetchInstanceDoc(host: string): Promise { host = toPuny(host); + const cached = cache.get(host); + if (cached) return cached; + const index = await Instances.findOne({ host }); if (index == null) { @@ -19,8 +25,10 @@ export async function registerOrFetchInstanceDoc(host: string): Promise