perf(server): reduce db query

This commit is contained in:
syuilo 2022-03-21 01:22:00 +09:00
parent c1ce301d24
commit 4c2d4d76e6
2 changed files with 24 additions and 5 deletions

View file

@ -28,11 +28,22 @@ export class Cache<T> {
this.cache.delete(key); this.cache.delete(key);
} }
public async fetch(key: string | null, fetcher: () => Promise<T>): Promise<T> { /**
* fetcherを呼び出して結果をキャッシュ&
* optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします
*/
public async fetch(key: string | null, fetcher: () => Promise<T>, validator?: (cachedValue: T) => boolean): Promise<T> {
const cachedValue = this.get(key); const cachedValue = this.get(key);
if (cachedValue !== undefined) { if (cachedValue !== undefined) {
// Cache HIT if (validator) {
return cachedValue; if (validator(cachedValue)) {
// Cache HIT
return cachedValue;
}
} else {
// Cache HIT
return cachedValue;
}
} }
// Cache MISS // Cache MISS

View file

@ -8,6 +8,10 @@ import { awaitAll, Promiseable } from '@/prelude/await-all.js';
import { populateEmojis } from '@/misc/populate-emojis.js'; import { populateEmojis } from '@/misc/populate-emojis.js';
import { getAntennas } from '@/misc/antenna-cache.js'; import { getAntennas } from '@/misc/antenna-cache.js';
import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js'; import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js';
import { Cache } from '@/misc/cache.js';
import { Instance } from '../entities/instance.js';
const userInstanceCache = new Cache<Instance | null>(1000 * 60 * 60 * 3);
type IsUserDetailed<Detailed extends boolean> = Detailed extends true ? Packed<'UserDetailed'> : Packed<'UserLite'>; type IsUserDetailed<Detailed extends boolean> = Detailed extends true ? Packed<'UserDetailed'> : Packed<'UserLite'>;
type IsMeAndIsUserDetailed<ExpectsMe extends boolean | null, Detailed extends boolean> = type IsMeAndIsUserDetailed<ExpectsMe extends boolean | null, Detailed extends boolean> =
@ -254,8 +258,11 @@ export class UserRepository extends Repository<User> {
isModerator: user.isModerator || falsy, isModerator: user.isModerator || falsy,
isBot: user.isBot || falsy, isBot: user.isBot || falsy,
isCat: user.isCat || falsy, isCat: user.isCat || falsy,
showTimelineReplies: user.showTimelineReplies || falsy, // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる
instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? { instance: user.host ? userInstanceCache.fetch(user.host,
() => Instances.findOne({ host: user.host }).then(x => x || null),
v => v != null
).then(instance => instance ? {
name: instance.name, name: instance.name,
softwareName: instance.softwareName, softwareName: instance.softwareName,
softwareVersion: instance.softwareVersion, softwareVersion: instance.softwareVersion,
@ -334,6 +341,7 @@ export class UserRepository extends Repository<User> {
mutedInstances: profile!.mutedInstances, mutedInstances: profile!.mutedInstances,
mutingNotificationTypes: profile!.mutingNotificationTypes, mutingNotificationTypes: profile!.mutingNotificationTypes,
emailNotificationTypes: profile!.emailNotificationTypes, emailNotificationTypes: profile!.emailNotificationTypes,
showTimelineReplies: user.showTimelineReplies || falsy,
} : {}), } : {}),
...(opts.includeSecrets ? { ...(opts.includeSecrets ? {