perf(server): reduce db query
This commit is contained in:
parent
aebd77ad38
commit
eb9e6d230f
2 changed files with 24 additions and 5 deletions
|
@ -28,12 +28,23 @@ 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) {
|
||||||
|
if (validator) {
|
||||||
|
if (validator(cachedValue)) {
|
||||||
// Cache HIT
|
// Cache HIT
|
||||||
return cachedValue;
|
return cachedValue;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Cache HIT
|
||||||
|
return cachedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cache MISS
|
// Cache MISS
|
||||||
const value = await fetcher();
|
const value = await fetcher();
|
||||||
|
|
|
@ -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 ? {
|
||||||
|
|
Loading…
Reference in a new issue