From 6110682cad8ba428b1ec55e5c5a0b5986da36ee5 Mon Sep 17 00:00:00 2001 From: Hazel K Date: Fri, 26 Jul 2024 12:35:35 -0400 Subject: [PATCH 01/12] feat: update MemoryKVCache to support capacity limits and LRU eviction --- packages/backend/src/core/CacheService.ts | 12 +-- .../backend/src/core/CustomEmojiService.ts | 2 +- packages/backend/src/core/RoleService.ts | 4 +- .../core/activitypub/ApDbResolverService.ts | 4 +- packages/backend/src/misc/cache.ts | 89 ++++++++++++------- .../src/server/api/AuthenticateService.ts | 2 +- 6 files changed, 70 insertions(+), 43 deletions(-) diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index d008e7ec52a3..c46824ddd3dd 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -56,10 +56,10 @@ export class CacheService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - this.userByIdCache = new MemoryKVCache(Infinity); - this.localUserByNativeTokenCache = new MemoryKVCache(Infinity); - this.localUserByIdCache = new MemoryKVCache(Infinity); - this.uriPersonCache = new MemoryKVCache(Infinity); + this.userByIdCache = new MemoryKVCache(Infinity, Infinity); + this.localUserByNativeTokenCache = new MemoryKVCache(Infinity, Infinity); + this.localUserByIdCache = new MemoryKVCache(Infinity, Infinity); + this.uriPersonCache = new MemoryKVCache(Infinity, Infinity); this.userProfileCache = new RedisKVCache(this.redisClient, 'userProfile', { lifetime: 1000 * 60 * 30, // 30m @@ -135,14 +135,14 @@ export class CacheService implements OnApplicationShutdown { if (user == null) { this.userByIdCache.delete(body.id); this.localUserByIdCache.delete(body.id); - for (const [k, v] of this.uriPersonCache.cache.entries()) { + for (const [k, v] of this.uriPersonCache.entries()) { if (v.value?.id === body.id) { this.uriPersonCache.delete(k); } } } else { this.userByIdCache.set(user.id, user); - for (const [k, v] of this.uriPersonCache.cache.entries()) { + for (const [k, v] of this.uriPersonCache.entries()) { if (v.value?.id === user.id) { this.uriPersonCache.set(k, user); } diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 7e11b9cdca15..27737317a9fa 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -40,7 +40,7 @@ export class CustomEmojiService implements OnApplicationShutdown { private moderationLogService: ModerationLogService, private globalEventService: GlobalEventService, ) { - this.cache = new MemoryKVCache(1000 * 60 * 60 * 12); + this.cache = new MemoryKVCache(1000 * 60 * 60 * 12, Infinity); this.localEmojisCache = new RedisSingleCache>(this.redisClient, 'localEmojis', { lifetime: 1000 * 60 * 30, // 30m diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 796677467364..58df607c6bb0 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -129,8 +129,8 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { ) { //this.onMessage = this.onMessage.bind(this); - this.rolesCache = new MemorySingleCache(1000 * 60 * 60 * 1); - this.roleAssignmentByUserIdCache = new MemoryKVCache(1000 * 60 * 60 * 1); + this.rolesCache = new MemorySingleCache(1000 * 60 * 60); + this.roleAssignmentByUserIdCache = new MemoryKVCache(1000 * 60 * 60, Infinity); this.redisForSub.on('message', this.onMessage); } diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index f6b70ead4455..3a70521cc054 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -54,8 +54,8 @@ export class ApDbResolverService implements OnApplicationShutdown { private cacheService: CacheService, private apPersonService: ApPersonService, ) { - this.publicKeyCache = new MemoryKVCache(Infinity); - this.publicKeyByUserIdCache = new MemoryKVCache(Infinity); + this.publicKeyCache = new MemoryKVCache(Infinity, Infinity); + this.publicKeyByUserIdCache = new MemoryKVCache(Infinity, Infinity); } @bindThis diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index bba64a06eff2..dc74ca1e059b 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -25,7 +25,7 @@ export class RedisKVCache { this.redisClient = redisClient; this.name = name; this.lifetime = opts.lifetime; - this.memoryCache = new MemoryKVCache(opts.memoryCacheLifetime); + this.memoryCache = new MemoryKVCache(opts.memoryCacheLifetime, Infinity); this.fetcher = opts.fetcher; this.toRedisConverter = opts.toRedisConverter; this.fromRedisConverter = opts.fromRedisConverter; @@ -185,24 +185,13 @@ export class RedisSingleCache { } // TODO: メモリ節約のためあまり参照されないキーを定期的に削除できるようにする? - export class MemoryKVCache { - /** - * データを持つマップ - * @deprecated これを直接操作するべきではない - */ - public cache: Map; - private lifetime: number; - private gcIntervalHandle: NodeJS.Timeout; + private readonly cache = new Map>; - constructor(lifetime: MemoryKVCache['lifetime']) { - this.cache = new Map(); - this.lifetime = lifetime; - - this.gcIntervalHandle = setInterval(() => { - this.gc(); - }, 1000 * 60 * 3); - } + constructor ( + private readonly lifetime: number, + private readonly capacity: number + ) {} @bindThis /** @@ -210,25 +199,42 @@ export class MemoryKVCache { * @deprecated これを直接呼び出すべきではない。InternalEventなどで変更を全てのプロセス/マシンに通知するべき */ public set(key: string, value: T): void { + this.delete(key); + + // If the map is full, then we need to evict something + if (this.cache.size >= this.capacity) { + this.evictOldestKey(); + } + this.cache.set(key, { - date: Date.now(), + timeout: setTimeout(() => this.delete(key), this.lifetime), + lastUsed: Date.now(), value, }); } @bindThis public get(key: string): T | undefined { - const cached = this.cache.get(key); - if (cached == null) return undefined; - if ((Date.now() - cached.date) > this.lifetime) { - this.cache.delete(key); - return undefined; + const entry = this.cache.get(key); + + // Update last-used time and reset eviction + if (entry) { + clearTimeout(entry.timeout); + entry.timeout = setTimeout(() => this.delete(key), this.lifetime); + entry.lastUsed = Date.now(); } - return cached.value; + + return entry?.value; } @bindThis public delete(key: string): void { + // Clear eviction timer + const timeout = this.cache.get(key)?.timeout; + if (timeout) { + clearTimeout(timeout); + } + this.cache.delete(key); } @@ -286,18 +292,39 @@ export class MemoryKVCache { @bindThis public gc(): void { - const now = Date.now(); - for (const [key, { date }] of this.cache.entries()) { - if ((now - date) > this.lifetime) { - this.cache.delete(key); - } - } + // no-op, remove later } @bindThis public dispose(): void { - clearInterval(this.gcIntervalHandle); + // no-op, remove later + } + + private evictOldestKey(): void { + let oldestKey; + + let oldestAge = Number.MAX_VALUE; + for (const [key, value] of this.cache.entries()) { + if (value.lastUsed < oldestAge) { + oldestAge = value.lastUsed; + oldestKey = key; + } + } + + if (oldestKey) { + this.delete(oldestKey); + } } + + public entries() { + return this.cache.entries(); + } +} + +interface CacheEntry { + timeout: NodeJS.Timeout; + lastUsed: number; + value: T; } export class MemorySingleCache { diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts index ddef8db9879a..890253e62f2a 100644 --- a/packages/backend/src/server/api/AuthenticateService.ts +++ b/packages/backend/src/server/api/AuthenticateService.ts @@ -37,7 +37,7 @@ export class AuthenticateService implements OnApplicationShutdown { private cacheService: CacheService, ) { - this.appCache = new MemoryKVCache(Infinity); + this.appCache = new MemoryKVCache(Infinity, Infinity); } @bindThis From 3009b0fd7c660e23678ec57770de2635c0c8c063 Mon Sep 17 00:00:00 2001 From: Hazel K Date: Fri, 26 Jul 2024 12:42:16 -0400 Subject: [PATCH 02/12] chore: implement memoryCacheCapacity limit for RedisKVCache --- packages/backend/src/core/CacheService.ts | 6 ++++++ packages/backend/src/core/ChannelFollowingService.ts | 1 + packages/backend/src/core/FederatedInstanceService.ts | 1 + packages/backend/src/core/PushNotificationService.ts | 1 + packages/backend/src/core/UserKeypairService.ts | 1 + packages/backend/src/core/UserListService.ts | 1 + packages/backend/src/misc/cache.ts | 3 ++- 7 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index c46824ddd3dd..e1f971f4620a 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -64,6 +64,7 @@ export class CacheService implements OnApplicationShutdown { this.userProfileCache = new RedisKVCache(this.redisClient, 'userProfile', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 10_000, fetcher: (key) => this.userProfilesRepository.findOneByOrFail({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), // TODO: date型の考慮 @@ -72,6 +73,7 @@ export class CacheService implements OnApplicationShutdown { this.userMutingsCache = new RedisKVCache>(this.redisClient, 'userMutings', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 1_000, fetcher: (key) => this.mutingsRepository.find({ where: { muterId: key }, select: ['muteeId'] }).then(xs => new Set(xs.map(x => x.muteeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), @@ -80,6 +82,7 @@ export class CacheService implements OnApplicationShutdown { this.userBlockingCache = new RedisKVCache>(this.redisClient, 'userBlocking', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 1_000, fetcher: (key) => this.blockingsRepository.find({ where: { blockerId: key }, select: ['blockeeId'] }).then(xs => new Set(xs.map(x => x.blockeeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), @@ -88,6 +91,7 @@ export class CacheService implements OnApplicationShutdown { this.userBlockedCache = new RedisKVCache>(this.redisClient, 'userBlocked', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 1_000, fetcher: (key) => this.blockingsRepository.find({ where: { blockeeId: key }, select: ['blockerId'] }).then(xs => new Set(xs.map(x => x.blockerId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), @@ -96,6 +100,7 @@ export class CacheService implements OnApplicationShutdown { this.renoteMutingsCache = new RedisKVCache>(this.redisClient, 'renoteMutings', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 1_000, fetcher: (key) => this.renoteMutingsRepository.find({ where: { muterId: key }, select: ['muteeId'] }).then(xs => new Set(xs.map(x => x.muteeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), @@ -104,6 +109,7 @@ export class CacheService implements OnApplicationShutdown { this.userFollowingsCache = new RedisKVCache | undefined>>(this.redisClient, 'userFollowings', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 1_000, fetcher: (key) => this.followingsRepository.find({ where: { followerId: key }, select: ['followeeId', 'withReplies'] }).then(xs => { const obj: Record | undefined> = {}; for (const x of xs) { diff --git a/packages/backend/src/core/ChannelFollowingService.ts b/packages/backend/src/core/ChannelFollowingService.ts index 12251595e2fa..0a12733c6c99 100644 --- a/packages/backend/src/core/ChannelFollowingService.ts +++ b/packages/backend/src/core/ChannelFollowingService.ts @@ -31,6 +31,7 @@ export class ChannelFollowingService implements OnModuleInit { this.userFollowingChannelsCache = new RedisKVCache>(this.redisClient, 'userFollowingChannels', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 1_000, fetcher: (key) => this.channelFollowingsRepository.find({ where: { followerId: key }, select: ['followeeId'], diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index 7aeeb781786c..405d67201f65 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -30,6 +30,7 @@ export class FederatedInstanceService implements OnApplicationShutdown { this.federatedInstanceCache = new RedisKVCache(this.redisClient, 'federatedInstance', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60 * 3, // 3m + memoryCacheCapacity: 5_000, fetcher: (key) => this.instancesRepository.findOneBy({ host: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => { diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts index 6a845b951de6..ad8df60d9889 100644 --- a/packages/backend/src/core/PushNotificationService.ts +++ b/packages/backend/src/core/PushNotificationService.ts @@ -65,6 +65,7 @@ export class PushNotificationService implements OnApplicationShutdown { this.subscriptionsCache = new RedisKVCache(this.redisClient, 'userSwSubscriptions', { lifetime: 1000 * 60 * 60 * 1, // 1h memoryCacheLifetime: 1000 * 60 * 3, // 3m + memoryCacheCapacity: 1_000, fetcher: (key) => this.swSubscriptionsRepository.findBy({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), diff --git a/packages/backend/src/core/UserKeypairService.ts b/packages/backend/src/core/UserKeypairService.ts index 51ac99179a6a..a4711c758df1 100644 --- a/packages/backend/src/core/UserKeypairService.ts +++ b/packages/backend/src/core/UserKeypairService.ts @@ -26,6 +26,7 @@ export class UserKeypairService implements OnApplicationShutdown { this.cache = new RedisKVCache(this.redisClient, 'userKeypair', { lifetime: 1000 * 60 * 60 * 24, // 24h memoryCacheLifetime: Infinity, + memoryCacheCapacity: Infinity, fetcher: (key) => this.userKeypairsRepository.findOneByOrFail({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index 6333356fe9e8..e751949740bb 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -49,6 +49,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { this.membersCache = new RedisKVCache>(this.redisClient, 'userListMembers', { lifetime: 1000 * 60 * 30, // 30m memoryCacheLifetime: 1000 * 60, // 1m + memoryCacheCapacity: 1_000, fetcher: (key) => this.userListMembershipsRepository.find({ where: { userListId: key }, select: ['userId'] }).then(xs => new Set(xs.map(x => x.userId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index dc74ca1e059b..9367fb0b2afa 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -18,6 +18,7 @@ export class RedisKVCache { constructor(redisClient: RedisKVCache['redisClient'], name: RedisKVCache['name'], opts: { lifetime: RedisKVCache['lifetime']; memoryCacheLifetime: number; + memoryCacheCapacity: number; fetcher: RedisKVCache['fetcher']; toRedisConverter: RedisKVCache['toRedisConverter']; fromRedisConverter: RedisKVCache['fromRedisConverter']; @@ -25,7 +26,7 @@ export class RedisKVCache { this.redisClient = redisClient; this.name = name; this.lifetime = opts.lifetime; - this.memoryCache = new MemoryKVCache(opts.memoryCacheLifetime, Infinity); + this.memoryCache = new MemoryKVCache(opts.memoryCacheLifetime, opts.memoryCacheCapacity); this.fetcher = opts.fetcher; this.toRedisConverter = opts.toRedisConverter; this.fromRedisConverter = opts.fromRedisConverter; From bf584d92a70975c343fc5fee53f59f272f27b921 Mon Sep 17 00:00:00 2001 From: Hazel K Date: Fri, 26 Jul 2024 15:13:33 -0400 Subject: [PATCH 03/12] fix: limit memory cache of user keypairs --- packages/backend/src/core/UserKeypairService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/core/UserKeypairService.ts b/packages/backend/src/core/UserKeypairService.ts index a4711c758df1..d888975772f1 100644 --- a/packages/backend/src/core/UserKeypairService.ts +++ b/packages/backend/src/core/UserKeypairService.ts @@ -25,8 +25,8 @@ export class UserKeypairService implements OnApplicationShutdown { ) { this.cache = new RedisKVCache(this.redisClient, 'userKeypair', { lifetime: 1000 * 60 * 60 * 24, // 24h - memoryCacheLifetime: Infinity, - memoryCacheCapacity: Infinity, + memoryCacheLifetime: 1000 * 60 * 60 * 12, // 12h + memoryCacheCapacity: 10_000, // Only local users have a keypair fetcher: (key) => this.userKeypairsRepository.findOneByOrFail({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), From 691da2161d1c5556674218339f2baeb830d3564a Mon Sep 17 00:00:00 2001 From: Hazel K Date: Fri, 26 Jul 2024 15:19:00 -0400 Subject: [PATCH 04/12] chore: fix missing comma in `cache.ts` --- packages/backend/src/misc/cache.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 9367fb0b2afa..10a28ac4d28c 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -191,7 +191,7 @@ export class MemoryKVCache { constructor ( private readonly lifetime: number, - private readonly capacity: number + private readonly capacity: number, ) {} @bindThis From 9d52f4e60f5ca064492b3a38212cb9ced83613e6 Mon Sep 17 00:00:00 2001 From: Hazel K Date: Fri, 26 Jul 2024 15:36:16 -0400 Subject: [PATCH 05/12] fix: set lifetime / capacity limits on all memory caches --- packages/backend/src/core/CacheService.ts | 8 ++++---- packages/backend/src/core/CustomEmojiService.ts | 2 +- packages/backend/src/core/RoleService.ts | 2 +- .../backend/src/core/activitypub/ApDbResolverService.ts | 4 ++-- packages/backend/src/misc/cache.ts | 1 - packages/backend/src/server/api/AuthenticateService.ts | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index e1f971f4620a..ae4d03d86361 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -56,10 +56,10 @@ export class CacheService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - this.userByIdCache = new MemoryKVCache(Infinity, Infinity); - this.localUserByNativeTokenCache = new MemoryKVCache(Infinity, Infinity); - this.localUserByIdCache = new MemoryKVCache(Infinity, Infinity); - this.uriPersonCache = new MemoryKVCache(Infinity, Infinity); + this.userByIdCache = new MemoryKVCache(1000 * 60 * 60 * 12, 15_000); // 12h (used by AP *and* Auth) + this.localUserByNativeTokenCache = new MemoryKVCache(1000 * 60 * 60 * 12, 10_000); // 12h (used by auth) + this.localUserByIdCache = new MemoryKVCache(1000 * 60 * 60 * 12, 10_000); // 12h (used by auth) + this.uriPersonCache = new MemoryKVCache(1000 * 60 * 60 * 12, 10_000); // 12h (used by AP) this.userProfileCache = new RedisKVCache(this.redisClient, 'userProfile', { lifetime: 1000 * 60 * 30, // 30m diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 27737317a9fa..844e2827fa73 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -40,7 +40,7 @@ export class CustomEmojiService implements OnApplicationShutdown { private moderationLogService: ModerationLogService, private globalEventService: GlobalEventService, ) { - this.cache = new MemoryKVCache(1000 * 60 * 60 * 12, Infinity); + this.cache = new MemoryKVCache(1000 * 60 * 60 * 12, 5_000); this.localEmojisCache = new RedisSingleCache>(this.redisClient, 'localEmojis', { lifetime: 1000 * 60 * 30, // 30m diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 58df607c6bb0..538735aefe9e 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -130,7 +130,7 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { //this.onMessage = this.onMessage.bind(this); this.rolesCache = new MemorySingleCache(1000 * 60 * 60); - this.roleAssignmentByUserIdCache = new MemoryKVCache(1000 * 60 * 60, Infinity); + this.roleAssignmentByUserIdCache = new MemoryKVCache(1000 * 60 * 60, 10_000); this.redisForSub.on('message', this.onMessage); } diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 3a70521cc054..f8f53eca7e3e 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -54,8 +54,8 @@ export class ApDbResolverService implements OnApplicationShutdown { private cacheService: CacheService, private apPersonService: ApPersonService, ) { - this.publicKeyCache = new MemoryKVCache(Infinity, Infinity); - this.publicKeyByUserIdCache = new MemoryKVCache(Infinity, Infinity); + this.publicKeyCache = new MemoryKVCache(1000 * 60 * 60 * 12, 15_000); // 12h (used by AP) + this.publicKeyByUserIdCache = new MemoryKVCache(1000 * 60 * 60 * 12, 15_000); // 12h (used by AP) } @bindThis diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 10a28ac4d28c..727024ddc589 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -185,7 +185,6 @@ export class RedisSingleCache { } } -// TODO: メモリ節約のためあまり参照されないキーを定期的に削除できるようにする? export class MemoryKVCache { private readonly cache = new Map>; diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts index 890253e62f2a..16a76fdaec87 100644 --- a/packages/backend/src/server/api/AuthenticateService.ts +++ b/packages/backend/src/server/api/AuthenticateService.ts @@ -37,7 +37,7 @@ export class AuthenticateService implements OnApplicationShutdown { private cacheService: CacheService, ) { - this.appCache = new MemoryKVCache(Infinity, Infinity); + this.appCache = new MemoryKVCache(1000 * 60 * 60 * 24 * 7, 1_000); // 1w } @bindThis From 924f54d2dfdc42922b7b979251215191ac605a14 Mon Sep 17 00:00:00 2001 From: Hazel K Date: Fri, 26 Jul 2024 23:14:09 -0400 Subject: [PATCH 06/12] deprecate unused `gc()` and `dispose()` methods --- packages/backend/src/misc/cache.ts | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 727024ddc589..9f18d226616b 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -90,15 +90,17 @@ export class RedisKVCache { // TODO: イベント発行して他プロセスのメモリキャッシュも更新できるようにする } + /** + * @deprecated No longer needed or used. + */ @bindThis - public gc() { - this.memoryCache.gc(); - } + public gc() {} + /** + * @deprecated No longer needed or used. + */ @bindThis - public dispose() { - this.memoryCache.dispose(); - } + public dispose() {} } export class RedisSingleCache { @@ -290,15 +292,17 @@ export class MemoryKVCache { return value; } + /** + * @deprecated No longer needed or used. + */ @bindThis - public gc(): void { - // no-op, remove later - } + public gc(): void {} + /** + * @deprecated No longer needed or used. + */ @bindThis - public dispose(): void { - // no-op, remove later - } + public dispose(): void {} private evictOldestKey(): void { let oldestKey; From 50083be5117ba982f42b4c3a421aba59fe72b5fb Mon Sep 17 00:00:00 2001 From: Hazel K Date: Sat, 27 Jul 2024 00:43:43 -0400 Subject: [PATCH 07/12] limit capacity of OAuth caches --- packages/backend/src/server/oauth/OAuth2ProviderService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/server/oauth/OAuth2ProviderService.ts b/packages/backend/src/server/oauth/OAuth2ProviderService.ts index e065c451f147..f419a095f94e 100644 --- a/packages/backend/src/server/oauth/OAuth2ProviderService.ts +++ b/packages/backend/src/server/oauth/OAuth2ProviderService.ts @@ -197,7 +197,7 @@ function getQueryMode(issuerUrl: string): oauth2orize.grant.Options['modes'] { * 2. oauth/decision will call load() to retrieve the parameters and then remove() */ class OAuth2Store { - #cache = new MemoryKVCache(1000 * 60 * 5); // expires after 5min + #cache = new MemoryKVCache(1000 * 60 * 5, 10_000); // expires after 5min load(req: OAuth2DecisionRequest, cb: (err: Error | null, txn?: OAuth2) => void): void { const { transaction_id } = req.body; @@ -257,7 +257,7 @@ export class OAuth2ProviderService { grantedToken?: string, revoked?: boolean, used?: boolean, - }>(1000 * 60 * 5); // expires after 5m + }>(1000 * 60 * 5, 10_000); // expires after 5m // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics // "Authorization servers MUST support PKCE [RFC7636]." From 2c03e6f3e8af6abcf067864108748f8edea268af Mon Sep 17 00:00:00 2001 From: Hazel K Date: Sat, 27 Jul 2024 00:44:39 -0400 Subject: [PATCH 08/12] remove unused `gc()` and `dispose()` methods --- packages/backend/src/core/CacheService.ts | 10 -------- .../src/core/ChannelFollowingService.ts | 10 -------- .../backend/src/core/CustomEmojiService.ts | 12 +--------- .../src/core/FederatedInstanceService.ts | 12 +--------- .../src/core/PushNotificationService.ts | 12 +--------- packages/backend/src/core/RoleService.ts | 1 - .../backend/src/core/UserKeypairService.ts | 12 +--------- packages/backend/src/core/UserListService.ts | 1 - .../core/activitypub/ApDbResolverService.ts | 13 +--------- packages/backend/src/misc/cache.ts | 24 ------------------- .../src/server/api/AuthenticateService.ts | 12 +--------- 11 files changed, 6 insertions(+), 113 deletions(-) diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index ae4d03d86361..6bcbe59d6560 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -188,16 +188,6 @@ export class CacheService implements OnApplicationShutdown { @bindThis public dispose(): void { this.redisForSub.off('message', this.onMessage); - this.userByIdCache.dispose(); - this.localUserByNativeTokenCache.dispose(); - this.localUserByIdCache.dispose(); - this.uriPersonCache.dispose(); - this.userProfileCache.dispose(); - this.userMutingsCache.dispose(); - this.userBlockingCache.dispose(); - this.userBlockedCache.dispose(); - this.renoteMutingsCache.dispose(); - this.userFollowingsCache.dispose(); } @bindThis diff --git a/packages/backend/src/core/ChannelFollowingService.ts b/packages/backend/src/core/ChannelFollowingService.ts index 0a12733c6c99..7ab04daec7dd 100644 --- a/packages/backend/src/core/ChannelFollowingService.ts +++ b/packages/backend/src/core/ChannelFollowingService.ts @@ -97,14 +97,4 @@ export class ChannelFollowingService implements OnModuleInit { } } } - - @bindThis - public dispose(): void { - this.userFollowingChannelsCache.dispose(); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } } diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 844e2827fa73..4afcc767b9c1 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -23,7 +23,7 @@ import { ModerationLogService } from '@/core/ModerationLogService.js'; const parseEmojiStrRegexp = /^([-\w]+)(?:@([\w.-]+))?$/; @Injectable() -export class CustomEmojiService implements OnApplicationShutdown { +export class CustomEmojiService { private cache: MemoryKVCache; public localEmojisCache: RedisSingleCache>; @@ -398,14 +398,4 @@ export class CustomEmojiService implements OnApplicationShutdown { public getEmojiByName(name: string): Promise { return this.emojisRepository.findOneBy({ name, host: IsNull() }); } - - @bindThis - public dispose(): void { - this.cache.dispose(); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } } diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index 405d67201f65..a7a5039f77d5 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -14,7 +14,7 @@ import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; @Injectable() -export class FederatedInstanceService implements OnApplicationShutdown { +export class FederatedInstanceService { public federatedInstanceCache: RedisKVCache; constructor( @@ -84,14 +84,4 @@ export class FederatedInstanceService implements OnApplicationShutdown { this.federatedInstanceCache.set(result.host, result); } - - @bindThis - public dispose(): void { - this.federatedInstanceCache.dispose(); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } } diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts index ad8df60d9889..3ed1583a66c1 100644 --- a/packages/backend/src/core/PushNotificationService.ts +++ b/packages/backend/src/core/PushNotificationService.ts @@ -47,7 +47,7 @@ function truncateBody(type: T, body: Pus } @Injectable() -export class PushNotificationService implements OnApplicationShutdown { +export class PushNotificationService { private subscriptionsCache: RedisKVCache; constructor( @@ -128,14 +128,4 @@ export class PushNotificationService implements OnApplicationShutdown { public refreshCache(userId: string): void { this.subscriptionsCache.refresh(userId); } - - @bindThis - public dispose(): void { - this.subscriptionsCache.dispose(); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } } diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 538735aefe9e..d08fc4b53e3a 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -648,7 +648,6 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { @bindThis public dispose(): void { this.redisForSub.off('message', this.onMessage); - this.roleAssignmentByUserIdCache.dispose(); } @bindThis diff --git a/packages/backend/src/core/UserKeypairService.ts b/packages/backend/src/core/UserKeypairService.ts index d888975772f1..3783c87a61eb 100644 --- a/packages/backend/src/core/UserKeypairService.ts +++ b/packages/backend/src/core/UserKeypairService.ts @@ -13,7 +13,7 @@ import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @Injectable() -export class UserKeypairService implements OnApplicationShutdown { +export class UserKeypairService { private cache: RedisKVCache; constructor( @@ -37,14 +37,4 @@ export class UserKeypairService implements OnApplicationShutdown { public async getUserKeypair(userId: MiUser['id']): Promise { return await this.cache.fetch(userId); } - - @bindThis - public dispose(): void { - this.cache.dispose(); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } } diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index e751949740bb..499ea923676a 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -151,7 +151,6 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { @bindThis public dispose(): void { this.redisForSub.off('message', this.onMessage); - this.membersCache.dispose(); } @bindThis diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index f8f53eca7e3e..291df452838a 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -34,7 +34,7 @@ export type UriParseResult = { }; @Injectable() -export class ApDbResolverService implements OnApplicationShutdown { +export class ApDbResolverService { private publicKeyCache: MemoryKVCache; private publicKeyByUserIdCache: MemoryKVCache; @@ -168,15 +168,4 @@ export class ApDbResolverService implements OnApplicationShutdown { key, }; } - - @bindThis - public dispose(): void { - this.publicKeyCache.dispose(); - this.publicKeyByUserIdCache.dispose(); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } } diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 9f18d226616b..5ab8464ec837 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -89,18 +89,6 @@ export class RedisKVCache { // TODO: イベント発行して他プロセスのメモリキャッシュも更新できるようにする } - - /** - * @deprecated No longer needed or used. - */ - @bindThis - public gc() {} - - /** - * @deprecated No longer needed or used. - */ - @bindThis - public dispose() {} } export class RedisSingleCache { @@ -292,18 +280,6 @@ export class MemoryKVCache { return value; } - /** - * @deprecated No longer needed or used. - */ - @bindThis - public gc(): void {} - - /** - * @deprecated No longer needed or used. - */ - @bindThis - public dispose(): void {} - private evictOldestKey(): void { let oldestKey; diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts index 16a76fdaec87..907b254e0b26 100644 --- a/packages/backend/src/server/api/AuthenticateService.ts +++ b/packages/backend/src/server/api/AuthenticateService.ts @@ -22,7 +22,7 @@ export class AuthenticationError extends Error { } @Injectable() -export class AuthenticateService implements OnApplicationShutdown { +export class AuthenticateService { private appCache: MemoryKVCache; constructor( @@ -90,14 +90,4 @@ export class AuthenticateService implements OnApplicationShutdown { } } } - - @bindThis - public dispose(): void { - this.appCache.dispose(); - } - - @bindThis - public onApplicationShutdown(signal?: string | undefined): void { - this.dispose(); - } } From 3b45246ee008baf73946161b46031b408973025d Mon Sep 17 00:00:00 2001 From: Hazel K Date: Sat, 27 Jul 2024 02:23:52 -0400 Subject: [PATCH 09/12] move cache parameters to configuration --- .config/docker_example.yml | 124 ++++++++++ .config/example.yml | 125 ++++++++++ .devcontainer/devcontainer.yml | 124 ++++++++++ chart/files/default.yml | 124 ++++++++++ packages/backend/src/config.ts | 222 ++++++++++++++++++ .../src/core/AvatarDecorationService.ts | 6 +- packages/backend/src/core/CacheService.ts | 48 ++-- .../src/core/ChannelFollowingService.ts | 9 +- .../backend/src/core/CustomEmojiService.ts | 6 +- .../src/core/FederatedInstanceService.ts | 10 +- .../src/core/PushNotificationService.ts | 6 +- packages/backend/src/core/RelayService.ts | 6 +- packages/backend/src/core/RoleService.ts | 8 +- .../backend/src/core/UserKeypairService.ts | 10 +- packages/backend/src/core/UserListService.ts | 10 +- .../core/activitypub/ApDbResolverService.ts | 4 +- .../processors/DeliverProcessorService.ts | 6 +- .../src/server/NodeinfoServerService.ts | 2 +- .../src/server/api/AuthenticateService.ts | 6 +- 19 files changed, 807 insertions(+), 49 deletions(-) diff --git a/.config/docker_example.yml b/.config/docker_example.yml index d347882d1a91..e799a82fe70e 100644 --- a/.config/docker_example.yml +++ b/.config/docker_example.yml @@ -175,6 +175,130 @@ id: 'aidx' # deliverJobMaxAttempts: 12 # inboxJobMaxAttempts: 8 +caches: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + userByIdMemoryLifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + userByIdMemoryCapacity: 15000 + + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + localUserByIdMemoryLifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + localUserByIdMemoryCapacity: 10000 + + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + userByTokenMemoryLifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + userByTokenMemoryCapacity: 10000 + + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + userByUriMemoryLifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + userByUriMemoryCapacity: 10000 + + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + userProfileRedisLifetime: 1800000 + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + userProfileMemoryLifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + userProfileMemoryCapacity: 10000 + + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + userKeyPairRedisLifetime: 86400000 + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + userKeyPairMemoryLifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + userKeyPairMemoryCapacity: 10000 + + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + rolesMemoryLifetime: 3600000 + + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + userRolesMemoryLifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + userRolesMemoryCapacity: 10000 + + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + userMutesRedisLifetime: 1800000 + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + userMutesMemoryLifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + userMutesMemoryCapacity: 1000 + + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + userBlocksRedisLifetime: 1800000 + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + userBlocksMemoryLifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + userBlocksMemoryCapacity: 1000 + + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + userFollowingsRedisLifetime: 1800000 + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + userFollowingsMemoryLifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + userFollowingsMemoryCapacity: 1000 + + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + userChannelsRedisLifetime: 1800000 + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + userChannelsMemoryLifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + userChannelsMemoryCapacity: 1000 + + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + publicKeysMemoryLifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + publicKeysMemoryCapacity: 15000 + + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + emojisMemoryLifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + emojisMemoryCapacity: 5000 + + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + localEmojisRedisLifetime: 1800000 + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + localEmojisMemoryLifetime: 180000 + + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + instanceRedisLifetime: 1800000 + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + instanceMemoryLifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + instanceMemoryCapacity: 5000 + + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + swSubscriptionRedisLifetime: 3600000 + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + swSubscriptionMemoryLifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + swSubscriptionMemoryCapacity: 1000 + + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + listMembershipRedisLifetime: 1800000 + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + listMembershipMemoryLifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + listMembershipMemoryCapacity: 1000 + + # Lifetime of client apps in memory. Default: 604800000 (1 week) + clientAppMemoryLifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + clientAppMemoryCapacity: 1000 + + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + avatarDecorationsMemoryLifetime: 1800000 + + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + relaysMemoryLifetime: 600000 + + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + suspendedHostsMemoryLifetime: 3600000 + + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + nodeInfoMemoryLifetime: 600000 + # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 diff --git a/.config/example.yml b/.config/example.yml index b11cbd137328..511ad4668ea0 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -245,6 +245,131 @@ id: 'aidx' #deliverJobMaxAttempts: 12 #inboxJobMaxAttempts: 8 +caches: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + userByIdMemoryLifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + userByIdMemoryCapacity: 15000 + + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + localUserByIdMemoryLifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + localUserByIdMemoryCapacity: 10000 + + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + userByTokenMemoryLifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + userByTokenMemoryCapacity: 10000 + + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + userByUriMemoryLifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + userByUriMemoryCapacity: 10000 + + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + userProfileRedisLifetime: 1800000 + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + userProfileMemoryLifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + userProfileMemoryCapacity: 10000 + + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + userKeyPairRedisLifetime: 86400000 + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + userKeyPairMemoryLifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + userKeyPairMemoryCapacity: 10000 + + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + rolesMemoryLifetime: 3600000 + + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + userRolesMemoryLifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + userRolesMemoryCapacity: 10000 + + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + userMutesRedisLifetime: 1800000 + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + userMutesMemoryLifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + userMutesMemoryCapacity: 1000 + + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + userBlocksRedisLifetime: 1800000 + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + userBlocksMemoryLifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + userBlocksMemoryCapacity: 1000 + + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + userFollowingsRedisLifetime: 1800000 + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + userFollowingsMemoryLifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + userFollowingsMemoryCapacity: 1000 + + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + userChannelsRedisLifetime: 1800000 + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + userChannelsMemoryLifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + userChannelsMemoryCapacity: 1000 + + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + publicKeysMemoryLifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + publicKeysMemoryCapacity: 15000 + + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + emojisMemoryLifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + emojisMemoryCapacity: 5000 + + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + localEmojisRedisLifetime: 1800000 + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + localEmojisMemoryLifetime: 180000 + + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + instanceRedisLifetime: 1800000 + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + instanceMemoryLifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + instanceMemoryCapacity: 5000 + + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + swSubscriptionRedisLifetime: 3600000 + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + swSubscriptionMemoryLifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + swSubscriptionMemoryCapacity: 1000 + + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + listMembershipRedisLifetime: 1800000 + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + listMembershipMemoryLifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + listMembershipMemoryCapacity: 1000 + + # Lifetime of client apps in memory. Default: 604800000 (1 week) + clientAppMemoryLifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + clientAppMemoryCapacity: 1000 + + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + avatarDecorationsMemoryLifetime: 1800000 + + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + relaysMemoryLifetime: 600000 + + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + suspendedHostsMemoryLifetime: 3600000 + + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + nodeInfoMemoryLifetime: 600000 + + # Local address used for outgoing requests #outgoingAddress: 127.0.0.1 diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml index beefcfd0a2d5..0703bb85d30d 100644 --- a/.devcontainer/devcontainer.yml +++ b/.devcontainer/devcontainer.yml @@ -168,6 +168,130 @@ id: 'aidx' # deliverJobMaxAttempts: 12 # inboxJobMaxAttempts: 8 +caches: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + userByIdMemoryLifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + userByIdMemoryCapacity: 15000 + + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + localUserByIdMemoryLifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + localUserByIdMemoryCapacity: 10000 + + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + userByTokenMemoryLifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + userByTokenMemoryCapacity: 10000 + + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + userByUriMemoryLifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + userByUriMemoryCapacity: 10000 + + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + userProfileRedisLifetime: 1800000 + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + userProfileMemoryLifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + userProfileMemoryCapacity: 10000 + + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + userKeyPairRedisLifetime: 86400000 + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + userKeyPairMemoryLifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + userKeyPairMemoryCapacity: 10000 + + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + rolesMemoryLifetime: 3600000 + + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + userRolesMemoryLifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + userRolesMemoryCapacity: 10000 + + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + userMutesRedisLifetime: 1800000 + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + userMutesMemoryLifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + userMutesMemoryCapacity: 1000 + + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + userBlocksRedisLifetime: 1800000 + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + userBlocksMemoryLifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + userBlocksMemoryCapacity: 1000 + + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + userFollowingsRedisLifetime: 1800000 + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + userFollowingsMemoryLifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + userFollowingsMemoryCapacity: 1000 + + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + userChannelsRedisLifetime: 1800000 + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + userChannelsMemoryLifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + userChannelsMemoryCapacity: 1000 + + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + publicKeysMemoryLifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + publicKeysMemoryCapacity: 15000 + + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + emojisMemoryLifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + emojisMemoryCapacity: 5000 + + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + localEmojisRedisLifetime: 1800000 + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + localEmojisMemoryLifetime: 180000 + + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + instanceRedisLifetime: 1800000 + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + instanceMemoryLifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + instanceMemoryCapacity: 5000 + + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + swSubscriptionRedisLifetime: 3600000 + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + swSubscriptionMemoryLifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + swSubscriptionMemoryCapacity: 1000 + + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + listMembershipRedisLifetime: 1800000 + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + listMembershipMemoryLifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + listMembershipMemoryCapacity: 1000 + + # Lifetime of client apps in memory. Default: 604800000 (1 week) + clientAppMemoryLifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + clientAppMemoryCapacity: 1000 + + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + avatarDecorationsMemoryLifetime: 1800000 + + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + relaysMemoryLifetime: 600000 + + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + suspendedHostsMemoryLifetime: 3600000 + + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + nodeInfoMemoryLifetime: 600000 + # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 diff --git a/chart/files/default.yml b/chart/files/default.yml index f98b8ebfee04..6bc5c008fa21 100644 --- a/chart/files/default.yml +++ b/chart/files/default.yml @@ -189,6 +189,130 @@ id: "aidx" # deliverJobMaxAttempts: 12 # inboxJobMaxAttempts: 8 +caches: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + userByIdMemoryLifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + userByIdMemoryCapacity: 15000 + + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + localUserByIdMemoryLifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + localUserByIdMemoryCapacity: 10000 + + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + userByTokenMemoryLifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + userByTokenMemoryCapacity: 10000 + + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + userByUriMemoryLifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + userByUriMemoryCapacity: 10000 + + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + userProfileRedisLifetime: 1800000 + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + userProfileMemoryLifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + userProfileMemoryCapacity: 10000 + + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + userKeyPairRedisLifetime: 86400000 + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + userKeyPairMemoryLifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + userKeyPairMemoryCapacity: 10000 + + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + rolesMemoryLifetime: 3600000 + + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + userRolesMemoryLifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + userRolesMemoryCapacity: 10000 + + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + userMutesRedisLifetime: 1800000 + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + userMutesMemoryLifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + userMutesMemoryCapacity: 1000 + + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + userBlocksRedisLifetime: 1800000 + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + userBlocksMemoryLifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + userBlocksMemoryCapacity: 1000 + + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + userFollowingsRedisLifetime: 1800000 + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + userFollowingsMemoryLifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + userFollowingsMemoryCapacity: 1000 + + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + userChannelsRedisLifetime: 1800000 + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + userChannelsMemoryLifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + userChannelsMemoryCapacity: 1000 + + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + publicKeysMemoryLifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + publicKeysMemoryCapacity: 15000 + + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + emojisMemoryLifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + emojisMemoryCapacity: 5000 + + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + localEmojisRedisLifetime: 1800000 + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + localEmojisMemoryLifetime: 180000 + + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + instanceRedisLifetime: 1800000 + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + instanceMemoryLifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + instanceMemoryCapacity: 5000 + + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + swSubscriptionRedisLifetime: 3600000 + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + swSubscriptionMemoryLifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + swSubscriptionMemoryCapacity: 1000 + + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + listMembershipRedisLifetime: 1800000 + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + listMembershipMemoryLifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + listMembershipMemoryCapacity: 1000 + + # Lifetime of client apps in memory. Default: 604800000 (1 week) + clientAppMemoryLifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + clientAppMemoryCapacity: 1000 + + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + avatarDecorationsMemoryLifetime: 1800000 + + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + relaysMemoryLifetime: 600000 + + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + suspendedHostsMemoryLifetime: 3600000 + + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + nodeInfoMemoryLifetime: 600000 + # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index 3e5a1e81cd70..51705afbd8b8 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -85,6 +85,80 @@ type Source = { relationshipJobPerSec?: number; deliverJobMaxAttempts?: number; inboxJobMaxAttempts?: number; + caches?: { + userByIdMemoryLifetime?: number; + userByIdMemoryCapacity?: number; + + localUserByIdMemoryLifetime?: number; + localUserByIdMemoryCapacity?: number; + + userByTokenMemoryLifetime?: number; + userByTokenMemoryCapacity?: number; + + userByUriMemoryLifetime?: number; + userByUriMemoryCapacity?: number; + + userProfileRedisLifetime?: number; + userProfileMemoryLifetime?: number; + userProfileMemoryCapacity?: number; + + userKeyPairRedisLifetime?: number; + userKeyPairMemoryLifetime?: number; + userKeyPairMemoryCapacity?: number; + + rolesMemoryLifetime?: number; + + userRolesMemoryLifetime?: number; + userRolesMemoryCapacity?: number; + + userMutesRedisLifetime?: number; + userMutesMemoryLifetime?: number; + userMutesMemoryCapacity?: number; + + userBlocksRedisLifetime?: number; + userBlocksMemoryLifetime?: number; + userBlocksMemoryCapacity?: number; + + userFollowingsRedisLifetime?: number; + userFollowingsMemoryLifetime?: number; + userFollowingsMemoryCapacity?: number; + + userChannelsRedisLifetime?: number; + userChannelsMemoryLifetime?: number; + userChannelsMemoryCapacity?: number; + + publicKeysMemoryLifetime?: number; + publicKeysMemoryCapacity?: number; + + emojisMemoryLifetime?: number; + emojisMemoryCapacity?: number; + + localEmojisRedisLifetime?: number; + localEmojisMemoryLifetime?: number; + + instanceRedisLifetime?: number; + instanceMemoryLifetime?: number; + instanceMemoryCapacity?: number; + + swSubscriptionRedisLifetime?: number; + swSubscriptionMemoryLifetime?: number; + swSubscriptionMemoryCapacity?: number; + + listMembershipRedisLifetime?: number; + listMembershipMemoryLifetime?: number; + listMembershipMemoryCapacity?: number; + + clientAppMemoryLifetime?: number; + clientAppMemoryCapacity?: number; + + avatarDecorationsMemoryLifetime?: number; + + relaysMemoryLifetime?: number; + + suspendedHostsMemoryLifetime?: number; + + nodeInfoMemoryLifetime?: number; + }; mediaProxy?: string; proxyRemoteFiles?: boolean; @@ -146,6 +220,80 @@ export type Config = { relationshipJobPerSec: number | undefined; deliverJobMaxAttempts: number | undefined; inboxJobMaxAttempts: number | undefined; + caches: { + userByIdMemoryLifetime: number; + userByIdMemoryCapacity: number; + + localUserByIdMemoryLifetime: number; + localUserByIdMemoryCapacity: number; + + userByTokenMemoryLifetime: number; + userByTokenMemoryCapacity: number; + + userByUriMemoryLifetime: number; + userByUriMemoryCapacity: number; + + userProfileRedisLifetime: number; + userProfileMemoryLifetime: number; + userProfileMemoryCapacity: number; + + userKeyPairRedisLifetime: number; + userKeyPairMemoryLifetime: number; + userKeyPairMemoryCapacity: number; + + rolesMemoryLifetime: number; + + userRolesMemoryLifetime: number; + userRolesMemoryCapacity: number; + + userMutesRedisLifetime: number; + userMutesMemoryLifetime: number; + userMutesMemoryCapacity: number; + + userBlocksRedisLifetime: number; + userBlocksMemoryLifetime: number; + userBlocksMemoryCapacity: number; + + userFollowingsRedisLifetime: number; + userFollowingsMemoryLifetime: number; + userFollowingsMemoryCapacity: number; + + userChannelsRedisLifetime: number; + userChannelsMemoryLifetime: number; + userChannelsMemoryCapacity: number; + + publicKeysMemoryLifetime: number; + publicKeysMemoryCapacity: number; + + emojisMemoryLifetime: number; + emojisMemoryCapacity: number; + + localEmojisRedisLifetime: number; + localEmojisMemoryLifetime: number; + + instanceRedisLifetime: number; + instanceMemoryLifetime: number; + instanceMemoryCapacity: number; + + swSubscriptionRedisLifetime: number; + swSubscriptionMemoryLifetime: number; + swSubscriptionMemoryCapacity: number; + + listMembershipRedisLifetime: number; + listMembershipMemoryLifetime: number; + listMembershipMemoryCapacity: number; + + clientAppMemoryLifetime: number; + clientAppMemoryCapacity: number; + + avatarDecorationsMemoryLifetime: number; + + relaysMemoryLifetime: number; + + suspendedHostsMemoryLifetime: number; + + nodeInfoMemoryLifetime: number; + }; proxyRemoteFiles: boolean | undefined; signToActivityPubGet: boolean | undefined; @@ -262,6 +410,80 @@ export function loadConfig(): Config { relationshipJobPerSec: config.relationshipJobPerSec, deliverJobMaxAttempts: config.deliverJobMaxAttempts, inboxJobMaxAttempts: config.inboxJobMaxAttempts, + caches: { + userByIdMemoryLifetime: config.caches?.userByIdMemoryLifetime ?? 43200000, + userByIdMemoryCapacity: config.caches?.userByIdMemoryCapacity ?? 15000, + + localUserByIdMemoryLifetime: config.caches?.localUserByIdMemoryLifetime ?? 43200000, + localUserByIdMemoryCapacity: config.caches?.localUserByIdMemoryCapacity ?? 10000, + + userByTokenMemoryLifetime: config.caches?.userByTokenMemoryLifetime ?? 43200000, + userByTokenMemoryCapacity: config.caches?.userByTokenMemoryCapacity ?? 10000, + + userByUriMemoryLifetime: config.caches?.userByUriMemoryLifetime ?? 43200000, + userByUriMemoryCapacity: config.caches?.userByUriMemoryCapacity ?? 10000, + + userProfileRedisLifetime: config.caches?.userProfileRedisLifetime ?? 1800000, + userProfileMemoryLifetime: config.caches?.userProfileMemoryLifetime ?? 60000, + userProfileMemoryCapacity: config.caches?.userProfileMemoryCapacity ?? 10000, + + userKeyPairRedisLifetime: config.caches?.userKeyPairRedisLifetime ?? 86400000, + userKeyPairMemoryLifetime: config.caches?.userKeyPairMemoryLifetime ?? 43200000, + userKeyPairMemoryCapacity: config.caches?.userKeyPairMemoryCapacity ?? 10000, + + rolesMemoryLifetime: config.caches?.rolesMemoryLifetime ?? 3600000, + + userRolesMemoryLifetime: config.caches?.userRolesMemoryLifetime ?? 3600000, + userRolesMemoryCapacity: config.caches?.userRolesMemoryCapacity ?? 10000, + + userMutesRedisLifetime: config.caches?.userMutesRedisLifetime ?? 1800000, + userMutesMemoryLifetime: config.caches?.userMutesMemoryLifetime ?? 60000, + userMutesMemoryCapacity: config.caches?.userMutesMemoryCapacity ?? 10000, + + userBlocksRedisLifetime: config.caches?.userBlocksRedisLifetime ?? 1800000, + userBlocksMemoryLifetime: config.caches?.userBlocksMemoryLifetime ?? 60000, + userBlocksMemoryCapacity: config.caches?.userBlocksMemoryCapacity ?? 10000, + + userFollowingsRedisLifetime: config.caches?.userFollowingsRedisLifetime ?? 1800000, + userFollowingsMemoryLifetime: config.caches?.userFollowingsMemoryLifetime ?? 60000, + userFollowingsMemoryCapacity: config.caches?.userFollowingsMemoryCapacity ?? 10000, + + userChannelsRedisLifetime: config.caches?.userChannelsRedisLifetime ?? 1800000, + userChannelsMemoryLifetime: config.caches?.userChannelsMemoryLifetime ?? 60000, + userChannelsMemoryCapacity: config.caches?.userChannelsMemoryCapacity ?? 1000, + + publicKeysMemoryLifetime: config.caches?.publicKeysMemoryLifetime ?? 43200000, + publicKeysMemoryCapacity: config.caches?.publicKeysMemoryCapacity ?? 15000, + + emojisMemoryLifetime: config.caches?.emojisMemoryLifetime ?? 43200000, + emojisMemoryCapacity: config.caches?.emojisMemoryCapacity ?? 5000, + + localEmojisRedisLifetime: config.caches?.localEmojisRedisLifetime ?? 1800000, + localEmojisMemoryLifetime: config.caches?.localEmojisMemoryLifetime ?? 180000, + + instanceRedisLifetime: config.caches?.instanceRedisLifetime ?? 1800000, + instanceMemoryLifetime: config.caches?.instanceMemoryLifetime ?? 180000, + instanceMemoryCapacity: config.caches?.instanceMemoryCapacity ?? 5000, + + swSubscriptionRedisLifetime: config.caches?.swSubscriptionRedisLifetime ?? 3600000, + swSubscriptionMemoryLifetime: config.caches?.swSubscriptionMemoryLifetime ?? 180000, + swSubscriptionMemoryCapacity: config.caches?.swSubscriptionMemoryCapacity ?? 1000, + + listMembershipRedisLifetime: config.caches?.listMembershipRedisLifetime ?? 1800000, + listMembershipMemoryLifetime: config.caches?.listMembershipMemoryLifetime ?? 60000, + listMembershipMemoryCapacity: config.caches?.listMembershipMemoryCapacity ?? 1000, + + clientAppMemoryLifetime: config.caches?.clientAppMemoryLifetime ?? 604800000, + clientAppMemoryCapacity: config.caches?.clientAppMemoryCapacity ?? 1000, + + avatarDecorationsMemoryLifetime: config.caches?.avatarDecorationsMemoryLifetime ?? 1800000, + + relaysMemoryLifetime: config.caches?.relaysMemoryLifetime ?? 600000, + + suspendedHostsMemoryLifetime: config.caches?.suspendedHostsMemoryLifetime ?? 3600000, + + nodeInfoMemoryLifetime: config.caches?.nodeInfoMemoryLifetime ?? 600000, + }, proxyRemoteFiles: config.proxyRemoteFiles, signToActivityPubGet: config.signToActivityPubGet ?? true, mediaProxy: externalMediaProxy ?? internalMediaProxy, diff --git a/packages/backend/src/core/AvatarDecorationService.ts b/packages/backend/src/core/AvatarDecorationService.ts index 8b54bbe01241..32f324f9b13a 100644 --- a/packages/backend/src/core/AvatarDecorationService.ts +++ b/packages/backend/src/core/AvatarDecorationService.ts @@ -13,12 +13,16 @@ import { bindThis } from '@/decorators.js'; import { MemorySingleCache } from '@/misc/cache.js'; import type { GlobalEvents } from '@/core/GlobalEventService.js'; import { ModerationLogService } from '@/core/ModerationLogService.js'; +import type { Config } from '@/config.js'; @Injectable() export class AvatarDecorationService implements OnApplicationShutdown { public cache: MemorySingleCache; constructor( + @Inject(DI.config) + config: Config, + @Inject(DI.redisForSub) private redisForSub: Redis.Redis, @@ -29,7 +33,7 @@ export class AvatarDecorationService implements OnApplicationShutdown { private moderationLogService: ModerationLogService, private globalEventService: GlobalEventService, ) { - this.cache = new MemorySingleCache(1000 * 60 * 30); + this.cache = new MemorySingleCache(config.caches.avatarDecorationsMemoryLifetime); this.redisForSub.on('message', this.onMessage); } diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index 6bcbe59d6560..15d5aa176891 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -13,6 +13,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; import type { GlobalEvents } from '@/core/GlobalEventService.js'; import type { OnApplicationShutdown } from '@nestjs/common'; +import type { Config } from "@/config.js"; @Injectable() export class CacheService implements OnApplicationShutdown { @@ -28,6 +29,9 @@ export class CacheService implements OnApplicationShutdown { public userFollowingsCache: RedisKVCache | undefined>>; constructor( + @Inject(DI.config) + config: Config, + @Inject(DI.redis) private redisClient: Redis.Redis, @@ -56,60 +60,60 @@ export class CacheService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - this.userByIdCache = new MemoryKVCache(1000 * 60 * 60 * 12, 15_000); // 12h (used by AP *and* Auth) - this.localUserByNativeTokenCache = new MemoryKVCache(1000 * 60 * 60 * 12, 10_000); // 12h (used by auth) - this.localUserByIdCache = new MemoryKVCache(1000 * 60 * 60 * 12, 10_000); // 12h (used by auth) - this.uriPersonCache = new MemoryKVCache(1000 * 60 * 60 * 12, 10_000); // 12h (used by AP) + this.userByIdCache = new MemoryKVCache(config.caches.userByIdMemoryLifetime, config.caches.userByIdMemoryCapacity); + this.localUserByNativeTokenCache = new MemoryKVCache(config.caches.userByTokenMemoryLifetime, config.caches.userByTokenMemoryCapacity); + this.localUserByIdCache = new MemoryKVCache(config.caches.localUserByIdMemoryLifetime, config.caches.localUserByIdMemoryCapacity); // 12h (used by auth) + this.uriPersonCache = new MemoryKVCache(config.caches.userByUriMemoryLifetime, config.caches.userByUriMemoryCapacity); this.userProfileCache = new RedisKVCache(this.redisClient, 'userProfile', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 10_000, + lifetime: config.caches.userProfileRedisLifetime, + memoryCacheLifetime: config.caches.userProfileMemoryLifetime, + memoryCacheCapacity: config.caches.userProfileMemoryCapacity, fetcher: (key) => this.userProfilesRepository.findOneByOrFail({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), // TODO: date型の考慮 }); this.userMutingsCache = new RedisKVCache>(this.redisClient, 'userMutings', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 1_000, + lifetime: config.caches.userMutesRedisLifetime, + memoryCacheLifetime: config.caches.userMutesMemoryLifetime, + memoryCacheCapacity: config.caches.userMutesMemoryCapacity, fetcher: (key) => this.mutingsRepository.find({ where: { muterId: key }, select: ['muteeId'] }).then(xs => new Set(xs.map(x => x.muteeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.userBlockingCache = new RedisKVCache>(this.redisClient, 'userBlocking', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 1_000, + lifetime: config.caches.userBlocksRedisLifetime, + memoryCacheLifetime: config.caches.userBlocksMemoryLifetime, + memoryCacheCapacity: config.caches.userBlocksMemoryCapacity, fetcher: (key) => this.blockingsRepository.find({ where: { blockerId: key }, select: ['blockeeId'] }).then(xs => new Set(xs.map(x => x.blockeeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.userBlockedCache = new RedisKVCache>(this.redisClient, 'userBlocked', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 1_000, + lifetime: config.caches.userBlocksRedisLifetime, + memoryCacheLifetime: config.caches.userBlocksMemoryLifetime, + memoryCacheCapacity: config.caches.userBlocksMemoryCapacity, fetcher: (key) => this.blockingsRepository.find({ where: { blockeeId: key }, select: ['blockerId'] }).then(xs => new Set(xs.map(x => x.blockerId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.renoteMutingsCache = new RedisKVCache>(this.redisClient, 'renoteMutings', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 1_000, + lifetime: config.caches.userMutesRedisLifetime, + memoryCacheLifetime: config.caches.userMutesMemoryLifetime, + memoryCacheCapacity: config.caches.userMutesMemoryCapacity, fetcher: (key) => this.renoteMutingsRepository.find({ where: { muterId: key }, select: ['muteeId'] }).then(xs => new Set(xs.map(x => x.muteeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.userFollowingsCache = new RedisKVCache | undefined>>(this.redisClient, 'userFollowings', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 1_000, + lifetime: config.caches.userFollowingsRedisLifetime, + memoryCacheLifetime: config.caches.userFollowingsMemoryLifetime, + memoryCacheCapacity: config.caches.userFollowingsMemoryCapacity, fetcher: (key) => this.followingsRepository.find({ where: { followerId: key }, select: ['followeeId', 'withReplies'] }).then(xs => { const obj: Record | undefined> = {}; for (const x of xs) { diff --git a/packages/backend/src/core/ChannelFollowingService.ts b/packages/backend/src/core/ChannelFollowingService.ts index 7ab04daec7dd..bafdad162413 100644 --- a/packages/backend/src/core/ChannelFollowingService.ts +++ b/packages/backend/src/core/ChannelFollowingService.ts @@ -13,12 +13,15 @@ import { GlobalEvents, GlobalEventService } from '@/core/GlobalEventService.js'; import { bindThis } from '@/decorators.js'; import type { MiLocalUser } from '@/models/User.js'; import { RedisKVCache } from '@/misc/cache.js'; +import type { Config } from "@/config.js"; @Injectable() export class ChannelFollowingService implements OnModuleInit { public userFollowingChannelsCache: RedisKVCache>; constructor( + @Inject(DI.config) + config: Config, @Inject(DI.redis) private redisClient: Redis.Redis, @Inject(DI.redisForSub) @@ -29,9 +32,9 @@ export class ChannelFollowingService implements OnModuleInit { private globalEventService: GlobalEventService, ) { this.userFollowingChannelsCache = new RedisKVCache>(this.redisClient, 'userFollowingChannels', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 1_000, + lifetime: config.caches.userChannelsRedisLifetime, + memoryCacheLifetime: config.caches.userChannelsMemoryLifetime, + memoryCacheCapacity: config.caches.userChannelsMemoryCapacity, fetcher: (key) => this.channelFollowingsRepository.find({ where: { followerId: key }, select: ['followeeId'], diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index 4afcc767b9c1..b59bd35892f2 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -40,11 +40,11 @@ export class CustomEmojiService { private moderationLogService: ModerationLogService, private globalEventService: GlobalEventService, ) { - this.cache = new MemoryKVCache(1000 * 60 * 60 * 12, 5_000); + this.cache = new MemoryKVCache(config.caches.emojisMemoryLifetime, config.caches.emojisMemoryCapacity); this.localEmojisCache = new RedisSingleCache>(this.redisClient, 'localEmojis', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60 * 3, // 3m + lifetime: config.caches.localEmojisRedisLifetime, + memoryCacheLifetime: config.caches.localEmojisMemoryLifetime, fetcher: () => this.emojisRepository.find({ where: { host: IsNull() } }).then(emojis => new Map(emojis.map(emoji => [emoji.name, emoji]))), toRedisConverter: (value) => JSON.stringify(Array.from(value.values())), fromRedisConverter: (value) => { diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index a7a5039f77d5..ad2a1def8986 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -12,12 +12,16 @@ import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; +import type { Config } from "@/config.js"; @Injectable() export class FederatedInstanceService { public federatedInstanceCache: RedisKVCache; constructor( + @Inject(DI.config) + config: Config, + @Inject(DI.redis) private redisClient: Redis.Redis, @@ -28,9 +32,9 @@ export class FederatedInstanceService { private idService: IdService, ) { this.federatedInstanceCache = new RedisKVCache(this.redisClient, 'federatedInstance', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60 * 3, // 3m - memoryCacheCapacity: 5_000, + lifetime: config.caches.instanceRedisLifetime, + memoryCacheLifetime: config.caches.instanceMemoryLifetime, + memoryCacheCapacity: config.caches.instanceMemoryCapacity, fetcher: (key) => this.instancesRepository.findOneBy({ host: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => { diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts index 3ed1583a66c1..c5c63069cf63 100644 --- a/packages/backend/src/core/PushNotificationService.ts +++ b/packages/backend/src/core/PushNotificationService.ts @@ -63,9 +63,9 @@ export class PushNotificationService { private metaService: MetaService, ) { this.subscriptionsCache = new RedisKVCache(this.redisClient, 'userSwSubscriptions', { - lifetime: 1000 * 60 * 60 * 1, // 1h - memoryCacheLifetime: 1000 * 60 * 3, // 3m - memoryCacheCapacity: 1_000, + lifetime: config.caches.swSubscriptionRedisLifetime, + memoryCacheLifetime: config.caches.swSubscriptionMemoryLifetime, + memoryCacheCapacity: config.caches.swSubscriptionMemoryCapacity, fetcher: (key) => this.swSubscriptionsRepository.findBy({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts index 8dd3d64f5b29..683656b0eb14 100644 --- a/packages/backend/src/core/RelayService.ts +++ b/packages/backend/src/core/RelayService.ts @@ -16,6 +16,7 @@ import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { DI } from '@/di-symbols.js'; import { deepClone } from '@/misc/clone.js'; import { bindThis } from '@/decorators.js'; +import type { Config } from "@/config.js"; const ACTOR_USERNAME = 'relay.actor' as const; @@ -24,6 +25,9 @@ export class RelayService { private relaysCache: MemorySingleCache; constructor( + @Inject(DI.config) + config: Config, + @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -35,7 +39,7 @@ export class RelayService { private createSystemUserService: CreateSystemUserService, private apRendererService: ApRendererService, ) { - this.relaysCache = new MemorySingleCache(1000 * 60 * 10); + this.relaysCache = new MemorySingleCache(config.caches.relaysMemoryLifetime); } @bindThis diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index d08fc4b53e3a..0270c515978a 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -30,6 +30,7 @@ import type { Packed } from '@/misc/json-schema.js'; import { FanoutTimelineService } from '@/core/FanoutTimelineService.js'; import { NotificationService } from '@/core/NotificationService.js'; import type { OnApplicationShutdown, OnModuleInit } from '@nestjs/common'; +import type { Config } from "@/config.js"; export type RolePolicies = { gtlAvailable: boolean; @@ -101,6 +102,9 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { constructor( private moduleRef: ModuleRef, + @Inject(DI.config) + config: Config, + @Inject(DI.redis) private redisClient: Redis.Redis, @@ -129,8 +133,8 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { ) { //this.onMessage = this.onMessage.bind(this); - this.rolesCache = new MemorySingleCache(1000 * 60 * 60); - this.roleAssignmentByUserIdCache = new MemoryKVCache(1000 * 60 * 60, 10_000); + this.rolesCache = new MemorySingleCache(config.caches.rolesMemoryLifetime); + this.roleAssignmentByUserIdCache = new MemoryKVCache(config.caches.userRolesMemoryLifetime, config.caches.userRolesMemoryCapacity); this.redisForSub.on('message', this.onMessage); } diff --git a/packages/backend/src/core/UserKeypairService.ts b/packages/backend/src/core/UserKeypairService.ts index 3783c87a61eb..1f830ea79e52 100644 --- a/packages/backend/src/core/UserKeypairService.ts +++ b/packages/backend/src/core/UserKeypairService.ts @@ -11,12 +11,16 @@ import { RedisKVCache } from '@/misc/cache.js'; import type { MiUserKeypair } from '@/models/UserKeypair.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; +import type { Config } from "@/config.js"; @Injectable() export class UserKeypairService { private cache: RedisKVCache; constructor( + @Inject(DI.config) + config: Config, + @Inject(DI.redis) private redisClient: Redis.Redis, @@ -24,9 +28,9 @@ export class UserKeypairService { private userKeypairsRepository: UserKeypairsRepository, ) { this.cache = new RedisKVCache(this.redisClient, 'userKeypair', { - lifetime: 1000 * 60 * 60 * 24, // 24h - memoryCacheLifetime: 1000 * 60 * 60 * 12, // 12h - memoryCacheCapacity: 10_000, // Only local users have a keypair + lifetime: config.caches.userKeyPairRedisLifetime, + memoryCacheLifetime: config.caches.userKeyPairMemoryLifetime, + memoryCacheCapacity: config.caches.userKeyPairMemoryCapacity, fetcher: (key) => this.userKeypairsRepository.findOneByOrFail({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index 499ea923676a..f10d756c41cb 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -20,6 +20,7 @@ import { bindThis } from '@/decorators.js'; import { QueueService } from '@/core/QueueService.js'; import { RedisKVCache } from '@/misc/cache.js'; import { RoleService } from '@/core/RoleService.js'; +import type { Config } from "@/config.js"; @Injectable() export class UserListService implements OnApplicationShutdown, OnModuleInit { @@ -31,6 +32,9 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { constructor( private moduleRef: ModuleRef, + @Inject(DI.config) + config: Config, + @Inject(DI.redis) private redisClient: Redis.Redis, @@ -47,9 +51,9 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { private queueService: QueueService, ) { this.membersCache = new RedisKVCache>(this.redisClient, 'userListMembers', { - lifetime: 1000 * 60 * 30, // 30m - memoryCacheLifetime: 1000 * 60, // 1m - memoryCacheCapacity: 1_000, + lifetime: config.caches.listMembershipRedisLifetime, + memoryCacheLifetime: config.caches.listMembershipMemoryLifetime, + memoryCacheCapacity: config.caches.listMembershipMemoryCapacity, fetcher: (key) => this.userListMembershipsRepository.find({ where: { userListId: key }, select: ['userId'] }).then(xs => new Set(xs.map(x => x.userId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index 291df452838a..cd95042bdbfb 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -54,8 +54,8 @@ export class ApDbResolverService { private cacheService: CacheService, private apPersonService: ApPersonService, ) { - this.publicKeyCache = new MemoryKVCache(1000 * 60 * 60 * 12, 15_000); // 12h (used by AP) - this.publicKeyByUserIdCache = new MemoryKVCache(1000 * 60 * 60 * 12, 15_000); // 12h (used by AP) + this.publicKeyCache = new MemoryKVCache(config.caches.publicKeysMemoryLifetime, config.caches.publicKeysMemoryCapacity); + this.publicKeyByUserIdCache = new MemoryKVCache(config.caches.publicKeysMemoryLifetime, config.caches.publicKeysMemoryCapacity); } @bindThis diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index d665945861e2..e6756115bf11 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -23,6 +23,7 @@ import { UtilityService } from '@/core/UtilityService.js'; import { bindThis } from '@/decorators.js'; import { QueueLoggerService } from '../QueueLoggerService.js'; import type { DeliverJobData } from '../types.js'; +import type { Config } from "@/config.js"; @Injectable() export class DeliverProcessorService { @@ -31,6 +32,9 @@ export class DeliverProcessorService { private latest: string | null; constructor( + @Inject(DI.config) + config: Config, + @Inject(DI.instancesRepository) private instancesRepository: InstancesRepository, @@ -45,7 +49,7 @@ export class DeliverProcessorService { private queueLoggerService: QueueLoggerService, ) { this.logger = this.queueLoggerService.logger.createSubLogger('deliver'); - this.suspendedHostsCache = new MemorySingleCache(1000 * 60 * 60); + this.suspendedHostsCache = new MemorySingleCache(config.caches.suspendedHostsMemoryLifetime); } @bindThis diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index cc18997fdc1c..77719d9f08db 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -134,7 +134,7 @@ export class NodeinfoServerService { return document; }; - const cache = new MemorySingleCache>>(1000 * 60 * 10); + const cache = new MemorySingleCache>>(this.config.caches.nodeInfoMemoryLifetime); fastify.get(nodeinfo2_1path, async (request, reply) => { const base = await cache.fetch(() => nodeinfo2(21)); diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts index 907b254e0b26..0942adfc9c0d 100644 --- a/packages/backend/src/server/api/AuthenticateService.ts +++ b/packages/backend/src/server/api/AuthenticateService.ts @@ -13,6 +13,7 @@ import type { MiApp } from '@/models/App.js'; import { CacheService } from '@/core/CacheService.js'; import isNativeToken from '@/misc/is-native-token.js'; import { bindThis } from '@/decorators.js'; +import type { Config } from '@/config.js'; export class AuthenticationError extends Error { constructor(message: string) { @@ -26,6 +27,9 @@ export class AuthenticateService { private appCache: MemoryKVCache; constructor( + @Inject(DI.config) + config: Config, + @Inject(DI.usersRepository) private usersRepository: UsersRepository, @@ -37,7 +41,7 @@ export class AuthenticateService { private cacheService: CacheService, ) { - this.appCache = new MemoryKVCache(1000 * 60 * 60 * 24 * 7, 1_000); // 1w + this.appCache = new MemoryKVCache(config.caches.clientAppMemoryLifetime, config.caches.clientAppMemoryCapacity); } @bindThis From 07d78c29e1f661d879855194f805bca72d91076f Mon Sep 17 00:00:00 2001 From: Hazel K Date: Sat, 27 Jul 2024 02:28:43 -0400 Subject: [PATCH 10/12] add sanity checks to all cache implementations --- packages/backend/src/misc/cache.ts | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 5ab8464ec837..d08b2dce12c9 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -23,6 +23,15 @@ export class RedisKVCache { toRedisConverter: RedisKVCache['toRedisConverter']; fromRedisConverter: RedisKVCache['fromRedisConverter']; }) { + if (opts.lifetime <= 0) { + throw new Error(`Redis cache lifetime of ${opts.lifetime} is invalid - it must be greater than zero`); + } + if (opts.memoryCacheLifetime <= 0) { + throw new Error(`Memory cache lifetime of ${opts.memoryCacheLifetime} is invalid - it must be greater than zero`); + } + if (opts.memoryCacheCapacity <= 0) { + throw new Error(`Memory cache capacity of ${opts.memoryCacheCapacity} is invalid - it must be greater than zero`); + } this.redisClient = redisClient; this.name = name; this.lifetime = opts.lifetime; @@ -107,6 +116,12 @@ export class RedisSingleCache { toRedisConverter: RedisSingleCache['toRedisConverter']; fromRedisConverter: RedisSingleCache['fromRedisConverter']; }) { + if (opts.lifetime <= 0) { + throw new Error(`Redis cache lifetime of ${opts.lifetime} is invalid - it must be greater than zero`); + } + if (opts.memoryCacheLifetime <= 0) { + throw new Error(`Memory cache lifetime of ${opts.memoryCacheLifetime} is invalid - it must be greater than zero`); + } this.redisClient = redisClient; this.name = name; this.lifetime = opts.lifetime; @@ -181,7 +196,14 @@ export class MemoryKVCache { constructor ( private readonly lifetime: number, private readonly capacity: number, - ) {} + ) { + if (lifetime <= 0) { + throw new Error(`Memory cache lifetime of ${lifetime} is invalid - it must be greater than zero`); + } + if (capacity <= 0) { + throw new Error(`Memory cache capacity of ${capacity} is invalid - it must be greater than zero`); + } + } @bindThis /** @@ -313,6 +335,9 @@ export class MemorySingleCache { private lifetime: number; constructor(lifetime: MemorySingleCache['lifetime']) { + if (lifetime <= 0) { + throw new Error(`Cache lifetime of ${lifetime} is invalid - it must be greater than zero`); + } this.lifetime = lifetime; } From 740550fcd0f1a8b3561fee476e6111120285c262 Mon Sep 17 00:00:00 2001 From: Hazel K Date: Sat, 27 Jul 2024 08:28:23 -0400 Subject: [PATCH 11/12] restructure cache config --- .config/docker_example.yml | 300 ++++++----- .config/example.yml | 300 ++++++----- .devcontainer/devcontainer.yml | 300 ++++++----- chart/files/default.yml | 300 ++++++----- packages/backend/src/config.ts | 467 ++++++++++-------- .../src/core/AvatarDecorationService.ts | 2 +- packages/backend/src/core/CacheService.ts | 32 +- .../src/core/ChannelFollowingService.ts | 4 +- .../backend/src/core/CustomEmojiService.ts | 5 +- .../src/core/FederatedInstanceService.ts | 4 +- .../backend/src/core/InstanceActorService.ts | 6 +- .../src/core/PushNotificationService.ts | 4 +- packages/backend/src/core/RelayService.ts | 2 +- packages/backend/src/core/RoleService.ts | 4 +- .../backend/src/core/UserKeypairService.ts | 4 +- packages/backend/src/core/UserListService.ts | 4 +- .../core/activitypub/ApDbResolverService.ts | 4 +- packages/backend/src/misc/cache.ts | 64 +-- .../processors/DeliverProcessorService.ts | 2 +- .../src/server/NodeinfoServerService.ts | 2 +- .../src/server/api/AuthenticateService.ts | 2 +- 21 files changed, 1026 insertions(+), 786 deletions(-) diff --git a/.config/docker_example.yml b/.config/docker_example.yml index e799a82fe70e..fdb00fffbab3 100644 --- a/.config/docker_example.yml +++ b/.config/docker_example.yml @@ -176,128 +176,184 @@ id: 'aidx' # inboxJobMaxAttempts: 8 caches: - # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) - userByIdMemoryLifetime: 43200000 - # Maximum number of ID->user lookups cached in memory. Default: 15000 - userByIdMemoryCapacity: 15000 - - # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) - localUserByIdMemoryLifetime: 43200000 - # Maximum number of ID->local user lookups cached in memory. Default: 10000 - localUserByIdMemoryCapacity: 10000 - - # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) - userByTokenMemoryLifetime: 43200000 - # Maximum number of token->user lookups cached in memory. Default: 10000 - userByTokenMemoryCapacity: 10000 - - # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) - userByUriMemoryLifetime: 43200000 - # Maximum number of URI->user lookups cached in memory. Default: 10000 - userByUriMemoryCapacity: 10000 - - # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) - userProfileRedisLifetime: 1800000 - # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) - userProfileMemoryLifetime: 60000 - # Maximum number of user profiles cached in memory. Default: 10000 - userProfileMemoryCapacity: 10000 - - # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) - userKeyPairRedisLifetime: 86400000 - # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) - userKeyPairMemoryLifetime: 43200000 - # Maximum number of user keypairs cached in memory. Default: 10000 - userKeyPairMemoryCapacity: 10000 - - # Lifetime of cached roles in memory. Default: 3600000 (1 hour) - rolesMemoryLifetime: 3600000 - - # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) - userRolesMemoryLifetime: 3600000 - # Maximum number of user roles cached in memory. Default: 10000 - userRolesMemoryCapacity: 10000 - - # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) - userMutesRedisLifetime: 1800000 - # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) - userMutesMemoryLifetime: 60000 - # Maximum number of user mutes cached in memory. Default: 1000 - userMutesMemoryCapacity: 1000 - - # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) - userBlocksRedisLifetime: 1800000 - # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) - userBlocksMemoryLifetime: 60000 - # Maximum number of user blocks cached in memory. Default: 1000 - userBlocksMemoryCapacity: 1000 - - # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) - userFollowingsRedisLifetime: 1800000 - # Lifetime of cached user followings in memory. Default: 60000 (1 minute) - userFollowingsMemoryLifetime: 60000 - # Maximum number of user followings cached in memory. Default: 1000 - userFollowingsMemoryCapacity: 1000 - - # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) - userChannelsRedisLifetime: 1800000 - # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) - userChannelsMemoryLifetime: 60000 - # Maximum number of user channel followings cached in memory. Default: 1000 - userChannelsMemoryCapacity: 1000 - - # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) - publicKeysMemoryLifetime: 43200000 - # Maximum number of public keys cached in memory. Default: 15000 - publicKeysMemoryCapacity: 15000 - - # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) - emojisMemoryLifetime: 43200000 - # Maximum number of emojis cached in memory. Default: 5000 - emojisMemoryCapacity: 5000 - - # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) - localEmojisRedisLifetime: 1800000 - # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) - localEmojisMemoryLifetime: 180000 - - # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) - instanceRedisLifetime: 1800000 - # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) - instanceMemoryLifetime: 180000 - # Maximum number of federated instances cached in memory. Default: 5000 - instanceMemoryCapacity: 5000 - - # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) - swSubscriptionRedisLifetime: 3600000 - # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) - swSubscriptionMemoryLifetime: 180000 - # Maximum number of service worker subscriptions cached in memory. Default: 1000 - swSubscriptionMemoryCapacity: 1000 - - # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) - listMembershipRedisLifetime: 1800000 - # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) - listMembershipMemoryLifetime: 60000 - # Maximum number of list memberships cached in memory. Default: 1000 - listMembershipMemoryCapacity: 1000 - - # Lifetime of client apps in memory. Default: 604800000 (1 week) - clientAppMemoryLifetime: 604800000 - # Maximum number of client apps cached in memory. Default: 1000 - clientAppMemoryCapacity: 1000 - - # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) - avatarDecorationsMemoryLifetime: 1800000 - - # Lifetime of cached relays in memory. Default: 600000 (10 minutes) - relaysMemoryLifetime: 600000 - - # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) - suspendedHostsMemoryLifetime: 3600000 - - # Lifetime of cached node info in memory. Default: 600000 (10 minutes) - nodeInfoMemoryLifetime: 600000 + localUserById: + memory: + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + capacity: 10000 + + userById: + memory: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + capacity: 15000 + + userByToken: + memory: + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userByUri: + memory: + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userProfile: + redis: + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + capacity: 10000 + + userKeyPair: + redis: + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + lifetime: 86400000 + memory: + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + capacity: 10000 + + roles: + memory: + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + userRoles: + memory: + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + capacity: 10000 + + userMutes: + redis: + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + capacity: 1000 + + userBlocks: + redis: + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + capacity: 1000 + + userFollowings: + redis: + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + capacity: 1000 + + userChannels: + redis: + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + capacity: 1000 + + publicKeys: + memory: + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + capacity: 15000 + + emojis: + memory: + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + capacity: 5000 + + localEmojis: + redis: + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + lifetime: 180000 + + instance: + redis: + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + capacity: 5000 + + swSubscription: + redis: + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + lifetime: 3600000 + memory: + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + capacity: 1000 + + listMembership: + redis: + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + capacity: 1000 + + clientApp: + memory: + # Lifetime of client apps in memory. Default: 604800000 (1 week) + lifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + capacity: 1000 + + avatarDecorations: + memory: + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + lifetime: 1800000 + + relays: + memory: + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + lifetime: 600000 + + suspendedHosts: + memory: + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + nodeInfo: + memory: + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + lifetime: 600000 # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 diff --git a/.config/example.yml b/.config/example.yml index 511ad4668ea0..b8740288900a 100644 --- a/.config/example.yml +++ b/.config/example.yml @@ -246,128 +246,184 @@ id: 'aidx' #inboxJobMaxAttempts: 8 caches: - # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) - userByIdMemoryLifetime: 43200000 - # Maximum number of ID->user lookups cached in memory. Default: 15000 - userByIdMemoryCapacity: 15000 - - # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) - localUserByIdMemoryLifetime: 43200000 - # Maximum number of ID->local user lookups cached in memory. Default: 10000 - localUserByIdMemoryCapacity: 10000 - - # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) - userByTokenMemoryLifetime: 43200000 - # Maximum number of token->user lookups cached in memory. Default: 10000 - userByTokenMemoryCapacity: 10000 - - # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) - userByUriMemoryLifetime: 43200000 - # Maximum number of URI->user lookups cached in memory. Default: 10000 - userByUriMemoryCapacity: 10000 - - # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) - userProfileRedisLifetime: 1800000 - # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) - userProfileMemoryLifetime: 60000 - # Maximum number of user profiles cached in memory. Default: 10000 - userProfileMemoryCapacity: 10000 - - # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) - userKeyPairRedisLifetime: 86400000 - # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) - userKeyPairMemoryLifetime: 43200000 - # Maximum number of user keypairs cached in memory. Default: 10000 - userKeyPairMemoryCapacity: 10000 - - # Lifetime of cached roles in memory. Default: 3600000 (1 hour) - rolesMemoryLifetime: 3600000 - - # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) - userRolesMemoryLifetime: 3600000 - # Maximum number of user roles cached in memory. Default: 10000 - userRolesMemoryCapacity: 10000 - - # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) - userMutesRedisLifetime: 1800000 - # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) - userMutesMemoryLifetime: 60000 - # Maximum number of user mutes cached in memory. Default: 1000 - userMutesMemoryCapacity: 1000 - - # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) - userBlocksRedisLifetime: 1800000 - # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) - userBlocksMemoryLifetime: 60000 - # Maximum number of user blocks cached in memory. Default: 1000 - userBlocksMemoryCapacity: 1000 - - # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) - userFollowingsRedisLifetime: 1800000 - # Lifetime of cached user followings in memory. Default: 60000 (1 minute) - userFollowingsMemoryLifetime: 60000 - # Maximum number of user followings cached in memory. Default: 1000 - userFollowingsMemoryCapacity: 1000 - - # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) - userChannelsRedisLifetime: 1800000 - # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) - userChannelsMemoryLifetime: 60000 - # Maximum number of user channel followings cached in memory. Default: 1000 - userChannelsMemoryCapacity: 1000 - - # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) - publicKeysMemoryLifetime: 43200000 - # Maximum number of public keys cached in memory. Default: 15000 - publicKeysMemoryCapacity: 15000 - - # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) - emojisMemoryLifetime: 43200000 - # Maximum number of emojis cached in memory. Default: 5000 - emojisMemoryCapacity: 5000 - - # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) - localEmojisRedisLifetime: 1800000 - # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) - localEmojisMemoryLifetime: 180000 - - # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) - instanceRedisLifetime: 1800000 - # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) - instanceMemoryLifetime: 180000 - # Maximum number of federated instances cached in memory. Default: 5000 - instanceMemoryCapacity: 5000 - - # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) - swSubscriptionRedisLifetime: 3600000 - # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) - swSubscriptionMemoryLifetime: 180000 - # Maximum number of service worker subscriptions cached in memory. Default: 1000 - swSubscriptionMemoryCapacity: 1000 - - # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) - listMembershipRedisLifetime: 1800000 - # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) - listMembershipMemoryLifetime: 60000 - # Maximum number of list memberships cached in memory. Default: 1000 - listMembershipMemoryCapacity: 1000 - - # Lifetime of client apps in memory. Default: 604800000 (1 week) - clientAppMemoryLifetime: 604800000 - # Maximum number of client apps cached in memory. Default: 1000 - clientAppMemoryCapacity: 1000 - - # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) - avatarDecorationsMemoryLifetime: 1800000 - - # Lifetime of cached relays in memory. Default: 600000 (10 minutes) - relaysMemoryLifetime: 600000 - - # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) - suspendedHostsMemoryLifetime: 3600000 - - # Lifetime of cached node info in memory. Default: 600000 (10 minutes) - nodeInfoMemoryLifetime: 600000 + localUserById: + memory: + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + capacity: 10000 + + userById: + memory: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + capacity: 15000 + + userByToken: + memory: + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userByUri: + memory: + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userProfile: + redis: + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + capacity: 10000 + + userKeyPair: + redis: + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + lifetime: 86400000 + memory: + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + capacity: 10000 + + roles: + memory: + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + userRoles: + memory: + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + capacity: 10000 + + userMutes: + redis: + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + capacity: 1000 + + userBlocks: + redis: + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + capacity: 1000 + + userFollowings: + redis: + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + capacity: 1000 + + userChannels: + redis: + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + capacity: 1000 + + publicKeys: + memory: + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + capacity: 15000 + + emojis: + memory: + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + capacity: 5000 + + localEmojis: + redis: + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + lifetime: 180000 + + instance: + redis: + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + capacity: 5000 + + swSubscription: + redis: + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + lifetime: 3600000 + memory: + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + capacity: 1000 + + listMembership: + redis: + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + capacity: 1000 + + clientApp: + memory: + # Lifetime of client apps in memory. Default: 604800000 (1 week) + lifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + capacity: 1000 + + avatarDecorations: + memory: + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + lifetime: 1800000 + + relays: + memory: + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + lifetime: 600000 + + suspendedHosts: + memory: + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + nodeInfo: + memory: + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + lifetime: 600000 # Local address used for outgoing requests diff --git a/.devcontainer/devcontainer.yml b/.devcontainer/devcontainer.yml index 0703bb85d30d..2dea30128f0d 100644 --- a/.devcontainer/devcontainer.yml +++ b/.devcontainer/devcontainer.yml @@ -169,128 +169,184 @@ id: 'aidx' # inboxJobMaxAttempts: 8 caches: - # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) - userByIdMemoryLifetime: 43200000 - # Maximum number of ID->user lookups cached in memory. Default: 15000 - userByIdMemoryCapacity: 15000 - - # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) - localUserByIdMemoryLifetime: 43200000 - # Maximum number of ID->local user lookups cached in memory. Default: 10000 - localUserByIdMemoryCapacity: 10000 - - # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) - userByTokenMemoryLifetime: 43200000 - # Maximum number of token->user lookups cached in memory. Default: 10000 - userByTokenMemoryCapacity: 10000 - - # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) - userByUriMemoryLifetime: 43200000 - # Maximum number of URI->user lookups cached in memory. Default: 10000 - userByUriMemoryCapacity: 10000 - - # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) - userProfileRedisLifetime: 1800000 - # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) - userProfileMemoryLifetime: 60000 - # Maximum number of user profiles cached in memory. Default: 10000 - userProfileMemoryCapacity: 10000 - - # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) - userKeyPairRedisLifetime: 86400000 - # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) - userKeyPairMemoryLifetime: 43200000 - # Maximum number of user keypairs cached in memory. Default: 10000 - userKeyPairMemoryCapacity: 10000 - - # Lifetime of cached roles in memory. Default: 3600000 (1 hour) - rolesMemoryLifetime: 3600000 - - # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) - userRolesMemoryLifetime: 3600000 - # Maximum number of user roles cached in memory. Default: 10000 - userRolesMemoryCapacity: 10000 - - # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) - userMutesRedisLifetime: 1800000 - # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) - userMutesMemoryLifetime: 60000 - # Maximum number of user mutes cached in memory. Default: 1000 - userMutesMemoryCapacity: 1000 - - # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) - userBlocksRedisLifetime: 1800000 - # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) - userBlocksMemoryLifetime: 60000 - # Maximum number of user blocks cached in memory. Default: 1000 - userBlocksMemoryCapacity: 1000 - - # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) - userFollowingsRedisLifetime: 1800000 - # Lifetime of cached user followings in memory. Default: 60000 (1 minute) - userFollowingsMemoryLifetime: 60000 - # Maximum number of user followings cached in memory. Default: 1000 - userFollowingsMemoryCapacity: 1000 - - # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) - userChannelsRedisLifetime: 1800000 - # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) - userChannelsMemoryLifetime: 60000 - # Maximum number of user channel followings cached in memory. Default: 1000 - userChannelsMemoryCapacity: 1000 - - # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) - publicKeysMemoryLifetime: 43200000 - # Maximum number of public keys cached in memory. Default: 15000 - publicKeysMemoryCapacity: 15000 - - # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) - emojisMemoryLifetime: 43200000 - # Maximum number of emojis cached in memory. Default: 5000 - emojisMemoryCapacity: 5000 - - # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) - localEmojisRedisLifetime: 1800000 - # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) - localEmojisMemoryLifetime: 180000 - - # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) - instanceRedisLifetime: 1800000 - # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) - instanceMemoryLifetime: 180000 - # Maximum number of federated instances cached in memory. Default: 5000 - instanceMemoryCapacity: 5000 - - # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) - swSubscriptionRedisLifetime: 3600000 - # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) - swSubscriptionMemoryLifetime: 180000 - # Maximum number of service worker subscriptions cached in memory. Default: 1000 - swSubscriptionMemoryCapacity: 1000 - - # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) - listMembershipRedisLifetime: 1800000 - # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) - listMembershipMemoryLifetime: 60000 - # Maximum number of list memberships cached in memory. Default: 1000 - listMembershipMemoryCapacity: 1000 - - # Lifetime of client apps in memory. Default: 604800000 (1 week) - clientAppMemoryLifetime: 604800000 - # Maximum number of client apps cached in memory. Default: 1000 - clientAppMemoryCapacity: 1000 - - # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) - avatarDecorationsMemoryLifetime: 1800000 - - # Lifetime of cached relays in memory. Default: 600000 (10 minutes) - relaysMemoryLifetime: 600000 - - # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) - suspendedHostsMemoryLifetime: 3600000 - - # Lifetime of cached node info in memory. Default: 600000 (10 minutes) - nodeInfoMemoryLifetime: 600000 + localUserById: + memory: + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + capacity: 10000 + + userById: + memory: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + capacity: 15000 + + userByToken: + memory: + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userByUri: + memory: + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userProfile: + redis: + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + capacity: 10000 + + userKeyPair: + redis: + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + lifetime: 86400000 + memory: + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + capacity: 10000 + + roles: + memory: + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + userRoles: + memory: + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + capacity: 10000 + + userMutes: + redis: + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + capacity: 1000 + + userBlocks: + redis: + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + capacity: 1000 + + userFollowings: + redis: + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + capacity: 1000 + + userChannels: + redis: + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + capacity: 1000 + + publicKeys: + memory: + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + capacity: 15000 + + emojis: + memory: + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + capacity: 5000 + + localEmojis: + redis: + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + lifetime: 180000 + + instance: + redis: + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + capacity: 5000 + + swSubscription: + redis: + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + lifetime: 3600000 + memory: + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + capacity: 1000 + + listMembership: + redis: + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + capacity: 1000 + + clientApp: + memory: + # Lifetime of client apps in memory. Default: 604800000 (1 week) + lifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + capacity: 1000 + + avatarDecorations: + memory: + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + lifetime: 1800000 + + relays: + memory: + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + lifetime: 600000 + + suspendedHosts: + memory: + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + nodeInfo: + memory: + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + lifetime: 600000 # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 diff --git a/chart/files/default.yml b/chart/files/default.yml index 6bc5c008fa21..987fd3a926ee 100644 --- a/chart/files/default.yml +++ b/chart/files/default.yml @@ -190,128 +190,184 @@ id: "aidx" # inboxJobMaxAttempts: 8 caches: - # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) - userByIdMemoryLifetime: 43200000 - # Maximum number of ID->user lookups cached in memory. Default: 15000 - userByIdMemoryCapacity: 15000 - - # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) - localUserByIdMemoryLifetime: 43200000 - # Maximum number of ID->local user lookups cached in memory. Default: 10000 - localUserByIdMemoryCapacity: 10000 - - # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) - userByTokenMemoryLifetime: 43200000 - # Maximum number of token->user lookups cached in memory. Default: 10000 - userByTokenMemoryCapacity: 10000 - - # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) - userByUriMemoryLifetime: 43200000 - # Maximum number of URI->user lookups cached in memory. Default: 10000 - userByUriMemoryCapacity: 10000 - - # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) - userProfileRedisLifetime: 1800000 - # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) - userProfileMemoryLifetime: 60000 - # Maximum number of user profiles cached in memory. Default: 10000 - userProfileMemoryCapacity: 10000 - - # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) - userKeyPairRedisLifetime: 86400000 - # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) - userKeyPairMemoryLifetime: 43200000 - # Maximum number of user keypairs cached in memory. Default: 10000 - userKeyPairMemoryCapacity: 10000 - - # Lifetime of cached roles in memory. Default: 3600000 (1 hour) - rolesMemoryLifetime: 3600000 - - # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) - userRolesMemoryLifetime: 3600000 - # Maximum number of user roles cached in memory. Default: 10000 - userRolesMemoryCapacity: 10000 - - # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) - userMutesRedisLifetime: 1800000 - # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) - userMutesMemoryLifetime: 60000 - # Maximum number of user mutes cached in memory. Default: 1000 - userMutesMemoryCapacity: 1000 - - # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) - userBlocksRedisLifetime: 1800000 - # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) - userBlocksMemoryLifetime: 60000 - # Maximum number of user blocks cached in memory. Default: 1000 - userBlocksMemoryCapacity: 1000 - - # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) - userFollowingsRedisLifetime: 1800000 - # Lifetime of cached user followings in memory. Default: 60000 (1 minute) - userFollowingsMemoryLifetime: 60000 - # Maximum number of user followings cached in memory. Default: 1000 - userFollowingsMemoryCapacity: 1000 - - # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) - userChannelsRedisLifetime: 1800000 - # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) - userChannelsMemoryLifetime: 60000 - # Maximum number of user channel followings cached in memory. Default: 1000 - userChannelsMemoryCapacity: 1000 - - # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) - publicKeysMemoryLifetime: 43200000 - # Maximum number of public keys cached in memory. Default: 15000 - publicKeysMemoryCapacity: 15000 - - # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) - emojisMemoryLifetime: 43200000 - # Maximum number of emojis cached in memory. Default: 5000 - emojisMemoryCapacity: 5000 - - # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) - localEmojisRedisLifetime: 1800000 - # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) - localEmojisMemoryLifetime: 180000 - - # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) - instanceRedisLifetime: 1800000 - # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) - instanceMemoryLifetime: 180000 - # Maximum number of federated instances cached in memory. Default: 5000 - instanceMemoryCapacity: 5000 - - # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) - swSubscriptionRedisLifetime: 3600000 - # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) - swSubscriptionMemoryLifetime: 180000 - # Maximum number of service worker subscriptions cached in memory. Default: 1000 - swSubscriptionMemoryCapacity: 1000 - - # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) - listMembershipRedisLifetime: 1800000 - # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) - listMembershipMemoryLifetime: 60000 - # Maximum number of list memberships cached in memory. Default: 1000 - listMembershipMemoryCapacity: 1000 - - # Lifetime of client apps in memory. Default: 604800000 (1 week) - clientAppMemoryLifetime: 604800000 - # Maximum number of client apps cached in memory. Default: 1000 - clientAppMemoryCapacity: 1000 - - # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) - avatarDecorationsMemoryLifetime: 1800000 - - # Lifetime of cached relays in memory. Default: 600000 (10 minutes) - relaysMemoryLifetime: 600000 - - # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) - suspendedHostsMemoryLifetime: 3600000 - - # Lifetime of cached node info in memory. Default: 600000 (10 minutes) - nodeInfoMemoryLifetime: 600000 + localUserById: + memory: + # Lifetime of cached ID->local user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->local user lookups cached in memory. Default: 10000 + capacity: 10000 + + userById: + memory: + # Lifetime of cached ID->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of ID->user lookups cached in memory. Default: 15000 + capacity: 15000 + + userByToken: + memory: + # Lifetime of cached token->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of token->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userByUri: + memory: + # Lifetime of cached URI->user lookups in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of URI->user lookups cached in memory. Default: 10000 + capacity: 10000 + + userProfile: + redis: + # Lifetime of cached user profiles in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user profiles in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user profiles cached in memory. Default: 10000 + capacity: 10000 + + userKeyPair: + redis: + # Lifetime of cached user keypairs in redis. Default: 86400000 (1 day) + lifetime: 86400000 + memory: + # Lifetime of cached user keypairs in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of user keypairs cached in memory. Default: 10000 + capacity: 10000 + + roles: + memory: + # Lifetime of cached roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + userRoles: + memory: + # Lifetime of cached user roles in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + # Maximum number of user roles cached in memory. Default: 10000 + capacity: 10000 + + userMutes: + redis: + # Lifetime of cached user mutes in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user mutes in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user mutes cached in memory. Default: 1000 + capacity: 1000 + + userBlocks: + redis: + # Lifetime of cached user blocks in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user blocks in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user blocks cached in memory. Default: 1000 + capacity: 1000 + + userFollowings: + redis: + # Lifetime of cached user followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user followings cached in memory. Default: 1000 + capacity: 1000 + + userChannels: + redis: + # Lifetime of cached user channel followings in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached user channel followings in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of user channel followings cached in memory. Default: 1000 + capacity: 1000 + + publicKeys: + memory: + # Lifetime of cached public keys in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of public keys cached in memory. Default: 15000 + capacity: 15000 + + emojis: + memory: + # Lifetime of cached emojis in memory. Default: 43200000 (12 hours) + lifetime: 43200000 + # Maximum number of emojis cached in memory. Default: 5000 + capacity: 5000 + + localEmojis: + redis: + # Lifetime of cached local emojis in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached local emojis in memory. Default: 180000 (3 minutes) + lifetime: 180000 + + instance: + redis: + # Lifetime of cached federated instances in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached federated instances in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of federated instances cached in memory. Default: 5000 + capacity: 5000 + + swSubscription: + redis: + # Lifetime of cached service worker subscriptions in redis. Default: 3600000 (1 hour) + lifetime: 3600000 + memory: + # Lifetime of cached service worker subscriptions in memory. Default: 180000 (3 minute) + lifetime: 180000 + # Maximum number of service worker subscriptions cached in memory. Default: 1000 + capacity: 1000 + + listMembership: + redis: + # Lifetime of cached list memberships in redis. Default: 1800000 (30 minutes) + lifetime: 1800000 + memory: + # Lifetime of cached list memberships in memory. Default: 60000 (1 minute) + lifetime: 60000 + # Maximum number of list memberships cached in memory. Default: 1000 + capacity: 1000 + + clientApp: + memory: + # Lifetime of client apps in memory. Default: 604800000 (1 week) + lifetime: 604800000 + # Maximum number of client apps cached in memory. Default: 1000 + capacity: 1000 + + avatarDecorations: + memory: + # Lifetime of cached avatar decorations in memory. Default: 1800000 (30 minutes) + lifetime: 1800000 + + relays: + memory: + # Lifetime of cached relays in memory. Default: 600000 (10 minutes) + lifetime: 600000 + + suspendedHosts: + memory: + # Lifetime of cached suspended hosts in memory. Default: 3600000 (1 hour) + lifetime: 3600000 + + nodeInfo: + memory: + # Lifetime of cached node info in memory. Default: 600000 (10 minutes) + lifetime: 600000 # IP address family used for outgoing request (ipv4, ipv6 or dual) #outgoingAddressFamily: ipv4 diff --git a/packages/backend/src/config.ts b/packages/backend/src/config.ts index 51705afbd8b8..cbc95e8c69da 100644 --- a/packages/backend/src/config.ts +++ b/packages/backend/src/config.ts @@ -86,78 +86,29 @@ type Source = { deliverJobMaxAttempts?: number; inboxJobMaxAttempts?: number; caches?: { - userByIdMemoryLifetime?: number; - userByIdMemoryCapacity?: number; - - localUserByIdMemoryLifetime?: number; - localUserByIdMemoryCapacity?: number; - - userByTokenMemoryLifetime?: number; - userByTokenMemoryCapacity?: number; - - userByUriMemoryLifetime?: number; - userByUriMemoryCapacity?: number; - - userProfileRedisLifetime?: number; - userProfileMemoryLifetime?: number; - userProfileMemoryCapacity?: number; - - userKeyPairRedisLifetime?: number; - userKeyPairMemoryLifetime?: number; - userKeyPairMemoryCapacity?: number; - - rolesMemoryLifetime?: number; - - userRolesMemoryLifetime?: number; - userRolesMemoryCapacity?: number; - - userMutesRedisLifetime?: number; - userMutesMemoryLifetime?: number; - userMutesMemoryCapacity?: number; - - userBlocksRedisLifetime?: number; - userBlocksMemoryLifetime?: number; - userBlocksMemoryCapacity?: number; - - userFollowingsRedisLifetime?: number; - userFollowingsMemoryLifetime?: number; - userFollowingsMemoryCapacity?: number; - - userChannelsRedisLifetime?: number; - userChannelsMemoryLifetime?: number; - userChannelsMemoryCapacity?: number; - - publicKeysMemoryLifetime?: number; - publicKeysMemoryCapacity?: number; - - emojisMemoryLifetime?: number; - emojisMemoryCapacity?: number; - - localEmojisRedisLifetime?: number; - localEmojisMemoryLifetime?: number; - - instanceRedisLifetime?: number; - instanceMemoryLifetime?: number; - instanceMemoryCapacity?: number; - - swSubscriptionRedisLifetime?: number; - swSubscriptionMemoryLifetime?: number; - swSubscriptionMemoryCapacity?: number; - - listMembershipRedisLifetime?: number; - listMembershipMemoryLifetime?: number; - listMembershipMemoryCapacity?: number; - - clientAppMemoryLifetime?: number; - clientAppMemoryCapacity?: number; - - avatarDecorationsMemoryLifetime?: number; - - relaysMemoryLifetime?: number; - - suspendedHostsMemoryLifetime?: number; - - nodeInfoMemoryLifetime?: number; + localUserById?: MemoryKVConfigPartial; + userById?: MemoryKVConfigPartial; + userByToken?: MemoryKVConfigPartial; + userByUri?: MemoryKVConfigPartial; + userProfile?: RedisKVConfigPartial; + userKeyPair?: RedisKVConfigPartial; + userRoles?: MemoryKVConfigPartial; + userMutes?: RedisKVConfigPartial; + userBlocks?: RedisKVConfigPartial; + userFollowings?: RedisKVConfigPartial; + userChannels?: RedisKVConfigPartial; + roles?: MemorySingleConfigPartial; + publicKeys?: MemoryKVConfigPartial; + emojis?: MemoryKVConfigPartial; + localEmojis?: RedisSingleConfigPartial; + instance?: RedisKVConfigPartial; + swSubscription?: RedisKVConfigPartial; + listMembership?: RedisKVConfigPartial; + clientApp?: MemoryKVConfigPartial; + avatarDecorations?: MemorySingleConfigPartial; + relays?: MemorySingleConfigPartial; + suspendedHosts?: MemorySingleConfigPartial; + nodeInfo?: MemorySingleConfigPartial; }; mediaProxy?: string; @@ -171,6 +122,27 @@ type Source = { deactivateAntennaThreshold?: number; pidFile: string; }; +interface MemorySingleConfigPartial { + memory?: { + lifetime?: number; + } +} +interface RedisSingleConfigPartial extends MemorySingleConfigPartial { + redis?: { + lifetime?: number; + } +} +interface MemoryKVConfigPartial extends MemorySingleConfigPartial { + memory?: { + lifetime?: number; + capacity?: number; + } +} +interface RedisKVConfigPartial extends MemoryKVConfigPartial { + redis?: { + lifetime?: number; + } +} export type Config = { url: string; @@ -221,78 +193,29 @@ export type Config = { deliverJobMaxAttempts: number | undefined; inboxJobMaxAttempts: number | undefined; caches: { - userByIdMemoryLifetime: number; - userByIdMemoryCapacity: number; - - localUserByIdMemoryLifetime: number; - localUserByIdMemoryCapacity: number; - - userByTokenMemoryLifetime: number; - userByTokenMemoryCapacity: number; - - userByUriMemoryLifetime: number; - userByUriMemoryCapacity: number; - - userProfileRedisLifetime: number; - userProfileMemoryLifetime: number; - userProfileMemoryCapacity: number; - - userKeyPairRedisLifetime: number; - userKeyPairMemoryLifetime: number; - userKeyPairMemoryCapacity: number; - - rolesMemoryLifetime: number; - - userRolesMemoryLifetime: number; - userRolesMemoryCapacity: number; - - userMutesRedisLifetime: number; - userMutesMemoryLifetime: number; - userMutesMemoryCapacity: number; - - userBlocksRedisLifetime: number; - userBlocksMemoryLifetime: number; - userBlocksMemoryCapacity: number; - - userFollowingsRedisLifetime: number; - userFollowingsMemoryLifetime: number; - userFollowingsMemoryCapacity: number; - - userChannelsRedisLifetime: number; - userChannelsMemoryLifetime: number; - userChannelsMemoryCapacity: number; - - publicKeysMemoryLifetime: number; - publicKeysMemoryCapacity: number; - - emojisMemoryLifetime: number; - emojisMemoryCapacity: number; - - localEmojisRedisLifetime: number; - localEmojisMemoryLifetime: number; - - instanceRedisLifetime: number; - instanceMemoryLifetime: number; - instanceMemoryCapacity: number; - - swSubscriptionRedisLifetime: number; - swSubscriptionMemoryLifetime: number; - swSubscriptionMemoryCapacity: number; - - listMembershipRedisLifetime: number; - listMembershipMemoryLifetime: number; - listMembershipMemoryCapacity: number; - - clientAppMemoryLifetime: number; - clientAppMemoryCapacity: number; - - avatarDecorationsMemoryLifetime: number; - - relaysMemoryLifetime: number; - - suspendedHostsMemoryLifetime: number; - - nodeInfoMemoryLifetime: number; + localUserById: MemoryKVConfig; + userById: MemoryKVConfig; + userByToken: MemoryKVConfig; + userByUri: MemoryKVConfig; + userProfile: RedisKVConfig; + userKeyPair: RedisKVConfig; + userRoles: MemoryKVConfig; + userMutes: RedisKVConfig; + userBlocks: RedisKVConfig; + userFollowings: RedisKVConfig; + userChannels: RedisKVConfig; + roles: MemorySingleConfig; + publicKeys: MemoryKVConfig; + emojis: MemoryKVConfig; + localEmojis: RedisSingleConfig; + instance: RedisKVConfig; + swSubscription: RedisKVConfig; + listMembership: RedisKVConfig; + clientApp: MemoryKVConfig; + avatarDecorations: MemorySingleConfig; + relays: MemorySingleConfig; + suspendedHosts: MemorySingleConfig; + nodeInfo: MemorySingleConfig; }; proxyRemoteFiles: boolean | undefined; signToActivityPubGet: boolean | undefined; @@ -325,6 +248,28 @@ export type Config = { pidFile: string; }; +export interface MemorySingleConfig { + memory: { + lifetime: number; + } +} +export interface RedisSingleConfig extends MemorySingleConfig { + redis: { + lifetime: number; + } +} +export interface MemoryKVConfig extends MemorySingleConfig { + memory: { + lifetime: number; + capacity: number; + } +} +export interface RedisKVConfig extends MemoryKVConfig { + redis: { + lifetime: number; + } +} + const _filename = fileURLToPath(import.meta.url); const _dirname = dirname(_filename); @@ -411,78 +356,168 @@ export function loadConfig(): Config { deliverJobMaxAttempts: config.deliverJobMaxAttempts, inboxJobMaxAttempts: config.inboxJobMaxAttempts, caches: { - userByIdMemoryLifetime: config.caches?.userByIdMemoryLifetime ?? 43200000, - userByIdMemoryCapacity: config.caches?.userByIdMemoryCapacity ?? 15000, - - localUserByIdMemoryLifetime: config.caches?.localUserByIdMemoryLifetime ?? 43200000, - localUserByIdMemoryCapacity: config.caches?.localUserByIdMemoryCapacity ?? 10000, - - userByTokenMemoryLifetime: config.caches?.userByTokenMemoryLifetime ?? 43200000, - userByTokenMemoryCapacity: config.caches?.userByTokenMemoryCapacity ?? 10000, - - userByUriMemoryLifetime: config.caches?.userByUriMemoryLifetime ?? 43200000, - userByUriMemoryCapacity: config.caches?.userByUriMemoryCapacity ?? 10000, - - userProfileRedisLifetime: config.caches?.userProfileRedisLifetime ?? 1800000, - userProfileMemoryLifetime: config.caches?.userProfileMemoryLifetime ?? 60000, - userProfileMemoryCapacity: config.caches?.userProfileMemoryCapacity ?? 10000, - - userKeyPairRedisLifetime: config.caches?.userKeyPairRedisLifetime ?? 86400000, - userKeyPairMemoryLifetime: config.caches?.userKeyPairMemoryLifetime ?? 43200000, - userKeyPairMemoryCapacity: config.caches?.userKeyPairMemoryCapacity ?? 10000, - - rolesMemoryLifetime: config.caches?.rolesMemoryLifetime ?? 3600000, - - userRolesMemoryLifetime: config.caches?.userRolesMemoryLifetime ?? 3600000, - userRolesMemoryCapacity: config.caches?.userRolesMemoryCapacity ?? 10000, - - userMutesRedisLifetime: config.caches?.userMutesRedisLifetime ?? 1800000, - userMutesMemoryLifetime: config.caches?.userMutesMemoryLifetime ?? 60000, - userMutesMemoryCapacity: config.caches?.userMutesMemoryCapacity ?? 10000, - - userBlocksRedisLifetime: config.caches?.userBlocksRedisLifetime ?? 1800000, - userBlocksMemoryLifetime: config.caches?.userBlocksMemoryLifetime ?? 60000, - userBlocksMemoryCapacity: config.caches?.userBlocksMemoryCapacity ?? 10000, - - userFollowingsRedisLifetime: config.caches?.userFollowingsRedisLifetime ?? 1800000, - userFollowingsMemoryLifetime: config.caches?.userFollowingsMemoryLifetime ?? 60000, - userFollowingsMemoryCapacity: config.caches?.userFollowingsMemoryCapacity ?? 10000, - - userChannelsRedisLifetime: config.caches?.userChannelsRedisLifetime ?? 1800000, - userChannelsMemoryLifetime: config.caches?.userChannelsMemoryLifetime ?? 60000, - userChannelsMemoryCapacity: config.caches?.userChannelsMemoryCapacity ?? 1000, - - publicKeysMemoryLifetime: config.caches?.publicKeysMemoryLifetime ?? 43200000, - publicKeysMemoryCapacity: config.caches?.publicKeysMemoryCapacity ?? 15000, - - emojisMemoryLifetime: config.caches?.emojisMemoryLifetime ?? 43200000, - emojisMemoryCapacity: config.caches?.emojisMemoryCapacity ?? 5000, - - localEmojisRedisLifetime: config.caches?.localEmojisRedisLifetime ?? 1800000, - localEmojisMemoryLifetime: config.caches?.localEmojisMemoryLifetime ?? 180000, - - instanceRedisLifetime: config.caches?.instanceRedisLifetime ?? 1800000, - instanceMemoryLifetime: config.caches?.instanceMemoryLifetime ?? 180000, - instanceMemoryCapacity: config.caches?.instanceMemoryCapacity ?? 5000, - - swSubscriptionRedisLifetime: config.caches?.swSubscriptionRedisLifetime ?? 3600000, - swSubscriptionMemoryLifetime: config.caches?.swSubscriptionMemoryLifetime ?? 180000, - swSubscriptionMemoryCapacity: config.caches?.swSubscriptionMemoryCapacity ?? 1000, - - listMembershipRedisLifetime: config.caches?.listMembershipRedisLifetime ?? 1800000, - listMembershipMemoryLifetime: config.caches?.listMembershipMemoryLifetime ?? 60000, - listMembershipMemoryCapacity: config.caches?.listMembershipMemoryCapacity ?? 1000, - - clientAppMemoryLifetime: config.caches?.clientAppMemoryLifetime ?? 604800000, - clientAppMemoryCapacity: config.caches?.clientAppMemoryCapacity ?? 1000, - - avatarDecorationsMemoryLifetime: config.caches?.avatarDecorationsMemoryLifetime ?? 1800000, - - relaysMemoryLifetime: config.caches?.relaysMemoryLifetime ?? 600000, - - suspendedHostsMemoryLifetime: config.caches?.suspendedHostsMemoryLifetime ?? 3600000, - - nodeInfoMemoryLifetime: config.caches?.nodeInfoMemoryLifetime ?? 600000, + localUserById: { + memory: { + lifetime: config.caches?.localUserById?.memory?.lifetime ?? 43200000, + capacity: config.caches?.localUserById?.memory?.capacity ?? 10000, + }, + }, + userById: { + memory: { + lifetime: config.caches?.userById?.memory?.lifetime ?? 43200000, + capacity: config.caches?.userById?.memory?.capacity ?? 15000, + }, + }, + userByToken: { + memory: { + lifetime: config.caches?.userByToken?.memory?.lifetime ?? 43200000, + capacity: config.caches?.userByToken?.memory?.capacity ?? 10000, + }, + }, + userByUri: { + memory: { + lifetime: config.caches?.userByUri?.memory?.lifetime ?? 43200000, + capacity: config.caches?.userByUri?.memory?.capacity ?? 10000, + }, + }, + userProfile: { + redis: { + lifetime: config.caches?.userProfile?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.userProfile?.memory?.lifetime ?? 60000, + capacity: config.caches?.userProfile?.memory?.capacity ?? 10000, + }, + }, + userKeyPair: { + redis: { + lifetime: config.caches?.userKeyPair?.redis?.lifetime ?? 86400000, + }, + memory: { + lifetime: config.caches?.userKeyPair?.memory?.lifetime ?? 43200000, + capacity: config.caches?.userKeyPair?.memory?.capacity ?? 10000, + }, + }, + userRoles: { + memory: { + lifetime: config.caches?.userRoles?.memory?.lifetime ?? 3600000, + capacity: config.caches?.userRoles?.memory?.capacity ?? 10000, + }, + }, + userMutes: { + redis: { + lifetime: config.caches?.userMutes?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.userMutes?.memory?.lifetime ?? 60000, + capacity: config.caches?.userMutes?.memory?.capacity ?? 10000, + }, + }, + userBlocks: { + redis: { + lifetime: config.caches?.userBlocks?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.userBlocks?.memory?.lifetime ?? 60000, + capacity: config.caches?.userBlocks?.memory?.capacity ?? 10000, + }, + }, + userFollowings: { + redis: { + lifetime: config.caches?.userFollowings?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.userFollowings?.memory?.lifetime ?? 60000, + capacity: config.caches?.userFollowings?.memory?.capacity ?? 10000, + }, + }, + userChannels: { + redis: { + lifetime: config.caches?.userChannels?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.userChannels?.memory?.lifetime ?? 60000, + capacity: config.caches?.userChannels?.memory?.capacity ?? 10000, + }, + }, + roles: { + memory: { + lifetime: config.caches?.roles?.memory?.lifetime ?? 3600000, + }, + }, + publicKeys: { + memory: { + lifetime: config.caches?.publicKeys?.memory?.lifetime ?? 43200000, + capacity: config.caches?.publicKeys?.memory?.capacity ?? 15000, + }, + }, + emojis: { + memory: { + lifetime: config.caches?.emojis?.memory?.lifetime ?? 43200000, + capacity: config.caches?.emojis?.memory?.capacity ?? 5000, + }, + }, + localEmojis: { + redis: { + lifetime: config.caches?.localEmojis?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.localEmojis?.memory?.lifetime ?? 180000, + }, + }, + instance: { + redis: { + lifetime: config.caches?.instance?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.instance?.memory?.lifetime ?? 180000, + capacity: config.caches?.instance?.memory?.capacity ?? 5000, + }, + }, + swSubscription: { + redis: { + lifetime: config.caches?.swSubscription?.redis?.lifetime ?? 3600000, + }, + memory: { + lifetime: config.caches?.swSubscription?.memory?.lifetime ?? 180000, + capacity: config.caches?.swSubscription?.memory?.capacity ?? 1000, + }, + }, + listMembership: { + redis: { + lifetime: config.caches?.listMembership?.redis?.lifetime ?? 1800000, + }, + memory: { + lifetime: config.caches?.listMembership?.memory?.lifetime ?? 60000, + capacity: config.caches?.listMembership?.memory?.capacity ?? 1000, + }, + }, + clientApp: { + memory: { + lifetime: config.caches?.clientApp?.memory?.lifetime ?? 604800000, + capacity: config.caches?.clientApp?.memory?.capacity ?? 1000, + }, + }, + avatarDecorations: { + memory: { + lifetime: config.caches?.avatarDecorations?.memory?.lifetime ?? 1800000, + }, + }, + relays: { + memory: { + lifetime: config.caches?.relays?.memory?.lifetime ?? 600000, + }, + }, + suspendedHosts: { + memory: { + lifetime: config.caches?.suspendedHosts?.memory?.lifetime ?? 3600000, + }, + }, + nodeInfo: { + memory: { + lifetime: config.caches?.nodeInfo?.memory?.lifetime ?? 600000, + }, + }, }, proxyRemoteFiles: config.proxyRemoteFiles, signToActivityPubGet: config.signToActivityPubGet ?? true, diff --git a/packages/backend/src/core/AvatarDecorationService.ts b/packages/backend/src/core/AvatarDecorationService.ts index 32f324f9b13a..e4cad681c36e 100644 --- a/packages/backend/src/core/AvatarDecorationService.ts +++ b/packages/backend/src/core/AvatarDecorationService.ts @@ -33,7 +33,7 @@ export class AvatarDecorationService implements OnApplicationShutdown { private moderationLogService: ModerationLogService, private globalEventService: GlobalEventService, ) { - this.cache = new MemorySingleCache(config.caches.avatarDecorationsMemoryLifetime); + this.cache = new MemorySingleCache(config.caches.avatarDecorations); this.redisForSub.on('message', this.onMessage); } diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index 15d5aa176891..11b65c22271f 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -60,60 +60,48 @@ export class CacheService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - this.userByIdCache = new MemoryKVCache(config.caches.userByIdMemoryLifetime, config.caches.userByIdMemoryCapacity); - this.localUserByNativeTokenCache = new MemoryKVCache(config.caches.userByTokenMemoryLifetime, config.caches.userByTokenMemoryCapacity); - this.localUserByIdCache = new MemoryKVCache(config.caches.localUserByIdMemoryLifetime, config.caches.localUserByIdMemoryCapacity); // 12h (used by auth) - this.uriPersonCache = new MemoryKVCache(config.caches.userByUriMemoryLifetime, config.caches.userByUriMemoryCapacity); + this.userByIdCache = new MemoryKVCache(config.caches.userById); + this.localUserByNativeTokenCache = new MemoryKVCache(config.caches.userByToken); + this.localUserByIdCache = new MemoryKVCache(config.caches.localUserById); // 12h (used by auth) + this.uriPersonCache = new MemoryKVCache(config.caches.userByUri); this.userProfileCache = new RedisKVCache(this.redisClient, 'userProfile', { - lifetime: config.caches.userProfileRedisLifetime, - memoryCacheLifetime: config.caches.userProfileMemoryLifetime, - memoryCacheCapacity: config.caches.userProfileMemoryCapacity, + config: config.caches.userProfile, fetcher: (key) => this.userProfilesRepository.findOneByOrFail({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), // TODO: date型の考慮 }); this.userMutingsCache = new RedisKVCache>(this.redisClient, 'userMutings', { - lifetime: config.caches.userMutesRedisLifetime, - memoryCacheLifetime: config.caches.userMutesMemoryLifetime, - memoryCacheCapacity: config.caches.userMutesMemoryCapacity, + config: config.caches.userMutes, fetcher: (key) => this.mutingsRepository.find({ where: { muterId: key }, select: ['muteeId'] }).then(xs => new Set(xs.map(x => x.muteeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.userBlockingCache = new RedisKVCache>(this.redisClient, 'userBlocking', { - lifetime: config.caches.userBlocksRedisLifetime, - memoryCacheLifetime: config.caches.userBlocksMemoryLifetime, - memoryCacheCapacity: config.caches.userBlocksMemoryCapacity, + config: config.caches.userBlocks, fetcher: (key) => this.blockingsRepository.find({ where: { blockerId: key }, select: ['blockeeId'] }).then(xs => new Set(xs.map(x => x.blockeeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.userBlockedCache = new RedisKVCache>(this.redisClient, 'userBlocked', { - lifetime: config.caches.userBlocksRedisLifetime, - memoryCacheLifetime: config.caches.userBlocksMemoryLifetime, - memoryCacheCapacity: config.caches.userBlocksMemoryCapacity, + config: config.caches.userBlocks, fetcher: (key) => this.blockingsRepository.find({ where: { blockeeId: key }, select: ['blockerId'] }).then(xs => new Set(xs.map(x => x.blockerId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.renoteMutingsCache = new RedisKVCache>(this.redisClient, 'renoteMutings', { - lifetime: config.caches.userMutesRedisLifetime, - memoryCacheLifetime: config.caches.userMutesMemoryLifetime, - memoryCacheCapacity: config.caches.userMutesMemoryCapacity, + config: config.caches.userMutes, fetcher: (key) => this.renoteMutingsRepository.find({ where: { muterId: key }, select: ['muteeId'] }).then(xs => new Set(xs.map(x => x.muteeId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), }); this.userFollowingsCache = new RedisKVCache | undefined>>(this.redisClient, 'userFollowings', { - lifetime: config.caches.userFollowingsRedisLifetime, - memoryCacheLifetime: config.caches.userFollowingsMemoryLifetime, - memoryCacheCapacity: config.caches.userFollowingsMemoryCapacity, + config: config.caches.userFollowings, fetcher: (key) => this.followingsRepository.find({ where: { followerId: key }, select: ['followeeId', 'withReplies'] }).then(xs => { const obj: Record | undefined> = {}; for (const x of xs) { diff --git a/packages/backend/src/core/ChannelFollowingService.ts b/packages/backend/src/core/ChannelFollowingService.ts index bafdad162413..80d3feb5a737 100644 --- a/packages/backend/src/core/ChannelFollowingService.ts +++ b/packages/backend/src/core/ChannelFollowingService.ts @@ -32,9 +32,7 @@ export class ChannelFollowingService implements OnModuleInit { private globalEventService: GlobalEventService, ) { this.userFollowingChannelsCache = new RedisKVCache>(this.redisClient, 'userFollowingChannels', { - lifetime: config.caches.userChannelsRedisLifetime, - memoryCacheLifetime: config.caches.userChannelsMemoryLifetime, - memoryCacheCapacity: config.caches.userChannelsMemoryCapacity, + config: config.caches.userChannels, fetcher: (key) => this.channelFollowingsRepository.find({ where: { followerId: key }, select: ['followeeId'], diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index b59bd35892f2..6f94fec9dfa2 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -40,11 +40,10 @@ export class CustomEmojiService { private moderationLogService: ModerationLogService, private globalEventService: GlobalEventService, ) { - this.cache = new MemoryKVCache(config.caches.emojisMemoryLifetime, config.caches.emojisMemoryCapacity); + this.cache = new MemoryKVCache(config.caches.emojis); this.localEmojisCache = new RedisSingleCache>(this.redisClient, 'localEmojis', { - lifetime: config.caches.localEmojisRedisLifetime, - memoryCacheLifetime: config.caches.localEmojisMemoryLifetime, + config: config.caches.localEmojis, fetcher: () => this.emojisRepository.find({ where: { host: IsNull() } }).then(emojis => new Map(emojis.map(emoji => [emoji.name, emoji]))), toRedisConverter: (value) => JSON.stringify(Array.from(value.values())), fromRedisConverter: (value) => { diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index ad2a1def8986..46d1ba1336ba 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -32,9 +32,7 @@ export class FederatedInstanceService { private idService: IdService, ) { this.federatedInstanceCache = new RedisKVCache(this.redisClient, 'federatedInstance', { - lifetime: config.caches.instanceRedisLifetime, - memoryCacheLifetime: config.caches.instanceMemoryLifetime, - memoryCacheCapacity: config.caches.instanceMemoryCapacity, + config: config.caches.instance, fetcher: (key) => this.instancesRepository.findOneBy({ host: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => { diff --git a/packages/backend/src/core/InstanceActorService.ts b/packages/backend/src/core/InstanceActorService.ts index 22c47297a34d..fa08e36c1c98 100644 --- a/packages/backend/src/core/InstanceActorService.ts +++ b/packages/backend/src/core/InstanceActorService.ts @@ -24,7 +24,11 @@ export class InstanceActorService { private createSystemUserService: CreateSystemUserService, ) { - this.cache = new MemorySingleCache(Infinity); + this.cache = new MemorySingleCache({ + memory: { + lifetime: Infinity, + }, + }); } @bindThis diff --git a/packages/backend/src/core/PushNotificationService.ts b/packages/backend/src/core/PushNotificationService.ts index c5c63069cf63..40350610664e 100644 --- a/packages/backend/src/core/PushNotificationService.ts +++ b/packages/backend/src/core/PushNotificationService.ts @@ -63,9 +63,7 @@ export class PushNotificationService { private metaService: MetaService, ) { this.subscriptionsCache = new RedisKVCache(this.redisClient, 'userSwSubscriptions', { - lifetime: config.caches.swSubscriptionRedisLifetime, - memoryCacheLifetime: config.caches.swSubscriptionMemoryLifetime, - memoryCacheCapacity: config.caches.swSubscriptionMemoryCapacity, + config: config.caches.swSubscription, fetcher: (key) => this.swSubscriptionsRepository.findBy({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts index 683656b0eb14..490521dcbf2b 100644 --- a/packages/backend/src/core/RelayService.ts +++ b/packages/backend/src/core/RelayService.ts @@ -39,7 +39,7 @@ export class RelayService { private createSystemUserService: CreateSystemUserService, private apRendererService: ApRendererService, ) { - this.relaysCache = new MemorySingleCache(config.caches.relaysMemoryLifetime); + this.relaysCache = new MemorySingleCache(config.caches.relays); } @bindThis diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index 0270c515978a..1a78951a7f4c 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -133,8 +133,8 @@ export class RoleService implements OnApplicationShutdown, OnModuleInit { ) { //this.onMessage = this.onMessage.bind(this); - this.rolesCache = new MemorySingleCache(config.caches.rolesMemoryLifetime); - this.roleAssignmentByUserIdCache = new MemoryKVCache(config.caches.userRolesMemoryLifetime, config.caches.userRolesMemoryCapacity); + this.rolesCache = new MemorySingleCache(config.caches.roles); + this.roleAssignmentByUserIdCache = new MemoryKVCache(config.caches.userRoles); this.redisForSub.on('message', this.onMessage); } diff --git a/packages/backend/src/core/UserKeypairService.ts b/packages/backend/src/core/UserKeypairService.ts index 1f830ea79e52..c83b51ea2a95 100644 --- a/packages/backend/src/core/UserKeypairService.ts +++ b/packages/backend/src/core/UserKeypairService.ts @@ -28,9 +28,7 @@ export class UserKeypairService { private userKeypairsRepository: UserKeypairsRepository, ) { this.cache = new RedisKVCache(this.redisClient, 'userKeypair', { - lifetime: config.caches.userKeyPairRedisLifetime, - memoryCacheLifetime: config.caches.userKeyPairMemoryLifetime, - memoryCacheCapacity: config.caches.userKeyPairMemoryCapacity, + config: config.caches.userKeyPair, fetcher: (key) => this.userKeypairsRepository.findOneByOrFail({ userId: key }), toRedisConverter: (value) => JSON.stringify(value), fromRedisConverter: (value) => JSON.parse(value), diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts index f10d756c41cb..619e68fec9f0 100644 --- a/packages/backend/src/core/UserListService.ts +++ b/packages/backend/src/core/UserListService.ts @@ -51,9 +51,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit { private queueService: QueueService, ) { this.membersCache = new RedisKVCache>(this.redisClient, 'userListMembers', { - lifetime: config.caches.listMembershipRedisLifetime, - memoryCacheLifetime: config.caches.listMembershipMemoryLifetime, - memoryCacheCapacity: config.caches.listMembershipMemoryCapacity, + config: config.caches.listMembership, fetcher: (key) => this.userListMembershipsRepository.find({ where: { userListId: key }, select: ['userId'] }).then(xs => new Set(xs.map(x => x.userId))), toRedisConverter: (value) => JSON.stringify(Array.from(value)), fromRedisConverter: (value) => new Set(JSON.parse(value)), diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index cd95042bdbfb..bdea62d80a8d 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -54,8 +54,8 @@ export class ApDbResolverService { private cacheService: CacheService, private apPersonService: ApPersonService, ) { - this.publicKeyCache = new MemoryKVCache(config.caches.publicKeysMemoryLifetime, config.caches.publicKeysMemoryCapacity); - this.publicKeyByUserIdCache = new MemoryKVCache(config.caches.publicKeysMemoryLifetime, config.caches.publicKeysMemoryCapacity); + this.publicKeyCache = new MemoryKVCache(config.caches.publicKeys); + this.publicKeyByUserIdCache = new MemoryKVCache(config.caches.publicKeys); } @bindThis diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index d08b2dce12c9..8e14ed49d740 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -5,6 +5,7 @@ import * as Redis from 'ioredis'; import { bindThis } from '@/decorators.js'; +import type { MemoryKVConfig, MemorySingleConfig, RedisKVConfig, RedisSingleConfig } from '@/config.js'; export class RedisKVCache { private redisClient: Redis.Redis; @@ -16,26 +17,24 @@ export class RedisKVCache { private fromRedisConverter: (value: string) => T | undefined; constructor(redisClient: RedisKVCache['redisClient'], name: RedisKVCache['name'], opts: { - lifetime: RedisKVCache['lifetime']; - memoryCacheLifetime: number; - memoryCacheCapacity: number; + config: RedisKVConfig; fetcher: RedisKVCache['fetcher']; toRedisConverter: RedisKVCache['toRedisConverter']; fromRedisConverter: RedisKVCache['fromRedisConverter']; }) { - if (opts.lifetime <= 0) { - throw new Error(`Redis cache lifetime of ${opts.lifetime} is invalid - it must be greater than zero`); + if (opts.config.redis.lifetime <= 0) { + throw new Error(`Redis cache lifetime of ${opts.config.redis.lifetime} is invalid - it must be greater than zero`); } - if (opts.memoryCacheLifetime <= 0) { - throw new Error(`Memory cache lifetime of ${opts.memoryCacheLifetime} is invalid - it must be greater than zero`); + if (opts.config.memory.lifetime <= 0) { + throw new Error(`Memory cache lifetime of ${opts.config.memory.lifetime} is invalid - it must be greater than zero`); } - if (opts.memoryCacheCapacity <= 0) { - throw new Error(`Memory cache capacity of ${opts.memoryCacheCapacity} is invalid - it must be greater than zero`); + if (opts.config.memory.capacity <= 0) { + throw new Error(`Memory cache capacity of ${opts.config.memory.capacity} is invalid - it must be greater than zero`); } this.redisClient = redisClient; this.name = name; - this.lifetime = opts.lifetime; - this.memoryCache = new MemoryKVCache(opts.memoryCacheLifetime, opts.memoryCacheCapacity); + this.lifetime = opts.config.redis.lifetime; + this.memoryCache = new MemoryKVCache(opts.config); this.fetcher = opts.fetcher; this.toRedisConverter = opts.toRedisConverter; this.fromRedisConverter = opts.fromRedisConverter; @@ -110,22 +109,21 @@ export class RedisSingleCache { private fromRedisConverter: (value: string) => T | undefined; constructor(redisClient: RedisSingleCache['redisClient'], name: RedisSingleCache['name'], opts: { - lifetime: RedisSingleCache['lifetime']; - memoryCacheLifetime: number; + config: RedisSingleConfig; fetcher: RedisSingleCache['fetcher']; toRedisConverter: RedisSingleCache['toRedisConverter']; fromRedisConverter: RedisSingleCache['fromRedisConverter']; }) { - if (opts.lifetime <= 0) { - throw new Error(`Redis cache lifetime of ${opts.lifetime} is invalid - it must be greater than zero`); + if (opts.config.redis.lifetime <= 0) { + throw new Error(`Redis cache lifetime of ${opts.config.redis.lifetime} is invalid - it must be greater than zero`); } - if (opts.memoryCacheLifetime <= 0) { - throw new Error(`Memory cache lifetime of ${opts.memoryCacheLifetime} is invalid - it must be greater than zero`); + if (opts.config.memory.lifetime <= 0) { + throw new Error(`Memory cache lifetime of ${opts.config.memory.lifetime} is invalid - it must be greater than zero`); } this.redisClient = redisClient; this.name = name; - this.lifetime = opts.lifetime; - this.memoryCache = new MemorySingleCache(opts.memoryCacheLifetime); + this.lifetime = opts.config.redis.lifetime; + this.memoryCache = new MemorySingleCache(opts.config); this.fetcher = opts.fetcher; this.toRedisConverter = opts.toRedisConverter; this.fromRedisConverter = opts.fromRedisConverter; @@ -192,17 +190,19 @@ export class RedisSingleCache { export class MemoryKVCache { private readonly cache = new Map>; + private readonly lifetime: number; + private readonly capacity: number; - constructor ( - private readonly lifetime: number, - private readonly capacity: number, - ) { - if (lifetime <= 0) { - throw new Error(`Memory cache lifetime of ${lifetime} is invalid - it must be greater than zero`); + constructor(config: MemoryKVConfig) { + if (config.memory.lifetime <= 0) { + throw new Error(`Memory cache lifetime of ${config.memory.lifetime} is invalid - it must be greater than zero`); } - if (capacity <= 0) { - throw new Error(`Memory cache capacity of ${capacity} is invalid - it must be greater than zero`); + if (config.memory.capacity <= 0) { + throw new Error(`Memory cache capacity of ${config.memory.capacity} is invalid - it must be greater than zero`); } + + this.lifetime = config.memory.lifetime; + this.capacity = config.memory.capacity; } @bindThis @@ -332,13 +332,13 @@ interface CacheEntry { export class MemorySingleCache { private cachedAt: number | null = null; private value: T | undefined; - private lifetime: number; + private readonly lifetime: number; - constructor(lifetime: MemorySingleCache['lifetime']) { - if (lifetime <= 0) { - throw new Error(`Cache lifetime of ${lifetime} is invalid - it must be greater than zero`); + constructor(config: MemorySingleConfig) { + if (config.memory.lifetime <= 0) { + throw new Error(`Cache lifetime of ${config.memory.lifetime} is invalid - it must be greater than zero`); } - this.lifetime = lifetime; + this.lifetime = config.memory.lifetime; } @bindThis diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index e6756115bf11..053937aa3f99 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -49,7 +49,7 @@ export class DeliverProcessorService { private queueLoggerService: QueueLoggerService, ) { this.logger = this.queueLoggerService.logger.createSubLogger('deliver'); - this.suspendedHostsCache = new MemorySingleCache(config.caches.suspendedHostsMemoryLifetime); + this.suspendedHostsCache = new MemorySingleCache(config.caches.suspendedHosts); } @bindThis diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index 77719d9f08db..cf7a885b3ad4 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -134,7 +134,7 @@ export class NodeinfoServerService { return document; }; - const cache = new MemorySingleCache>>(this.config.caches.nodeInfoMemoryLifetime); + const cache = new MemorySingleCache>>(this.config.caches.nodeInfo); fastify.get(nodeinfo2_1path, async (request, reply) => { const base = await cache.fetch(() => nodeinfo2(21)); diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts index 0942adfc9c0d..77132a66b8eb 100644 --- a/packages/backend/src/server/api/AuthenticateService.ts +++ b/packages/backend/src/server/api/AuthenticateService.ts @@ -41,7 +41,7 @@ export class AuthenticateService { private cacheService: CacheService, ) { - this.appCache = new MemoryKVCache(config.caches.clientAppMemoryLifetime, config.caches.clientAppMemoryCapacity); + this.appCache = new MemoryKVCache(config.caches.clientApp); } @bindThis From 2d9d548c0731771beeeb339665ae3cf110df4336 Mon Sep 17 00:00:00 2001 From: Hazel K Date: Sat, 27 Jul 2024 09:12:30 -0400 Subject: [PATCH 12/12] summarize changes in CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d48d14c71d7..99a28e374f23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ ### Server - Feat: レートリミット制限に引っかかったときに`Retry-After`ヘッダーを返すように (#13949) +- Feat: expose configuration for Redis and Memory Cache parameters - Enhance: エンドポイント`clips/update`の必須項目を`clipId`のみに - Enhance: エンドポイント`admin/roles/update`の必須項目を`roleId`のみに - Enhance: エンドポイント`pages/update`の必須項目を`pageId`のみに @@ -78,6 +79,8 @@ - Fix: リノートのミュートが適用されるまでに時間がかかることがある問題を修正 (Cherry-picked from https://github.com/Type4ny-Project/Type4ny/commit/e9601029b52e0ad43d9131b555b614e56c84ebc1) - Fix: Steaming APIが不正なデータを受けた場合の動作が不安定である問題 #14251 +- Fix: Prevent memory leak from memory caches (#14310) +- Fix: More reliable memory cache eviction (#14311) ### Misskey.js - Feat: `/drive/files/create` のリクエストに対応(`multipart/form-data`に対応)