summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2022-03-21 01:22:00 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2022-03-21 01:22:00 +0900
commiteb9e6d230f41798615e45f00b036e0a48e3ac044 (patch)
tree1c0e368f02eaa1ca9597d2063ac69dfd8906b733
parentperf(server): reduce db query (diff)
downloadmisskey-eb9e6d230f41798615e45f00b036e0a48e3ac044.tar.gz
misskey-eb9e6d230f41798615e45f00b036e0a48e3ac044.tar.bz2
misskey-eb9e6d230f41798615e45f00b036e0a48e3ac044.zip
perf(server): reduce db query
-rw-r--r--packages/backend/src/misc/cache.ts17
-rw-r--r--packages/backend/src/models/repositories/user.ts12
2 files changed, 24 insertions, 5 deletions
diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts
index 76835b44b1..e9966b7785 100644
--- a/packages/backend/src/misc/cache.ts
+++ b/packages/backend/src/misc/cache.ts
@@ -28,11 +28,22 @@ export class Cache<T> {
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);
if (cachedValue !== undefined) {
- // Cache HIT
- return cachedValue;
+ if (validator) {
+ if (validator(cachedValue)) {
+ // Cache HIT
+ return cachedValue;
+ }
+ } else {
+ // Cache HIT
+ return cachedValue;
+ }
}
// Cache MISS
diff --git a/packages/backend/src/models/repositories/user.ts b/packages/backend/src/models/repositories/user.ts
index a909ab3ba6..17b7987a4e 100644
--- a/packages/backend/src/models/repositories/user.ts
+++ b/packages/backend/src/models/repositories/user.ts
@@ -8,6 +8,10 @@ import { awaitAll, Promiseable } from '@/prelude/await-all.js';
import { populateEmojis } from '@/misc/populate-emojis.js';
import { getAntennas } from '@/misc/antenna-cache.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 IsMeAndIsUserDetailed<ExpectsMe extends boolean | null, Detailed extends boolean> =
@@ -254,8 +258,11 @@ export class UserRepository extends Repository<User> {
isModerator: user.isModerator || falsy,
isBot: user.isBot || falsy,
isCat: user.isCat || falsy,
- showTimelineReplies: user.showTimelineReplies || falsy,
- instance: user.host ? Instances.findOne({ host: user.host }).then(instance => instance ? {
+ // TODO: typeorm 3.0にしたら .then(x => x || null) は消せる
+ 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,
softwareName: instance.softwareName,
softwareVersion: instance.softwareVersion,
@@ -334,6 +341,7 @@ export class UserRepository extends Repository<User> {
mutedInstances: profile!.mutedInstances,
mutingNotificationTypes: profile!.mutingNotificationTypes,
emailNotificationTypes: profile!.emailNotificationTypes,
+ showTimelineReplies: user.showTimelineReplies || falsy,
} : {}),
...(opts.includeSecrets ? {