From 2e486f02ffb83192fd46fd231fb3604e1b982416 Mon Sep 17 00:00:00 2001 From: Hazelnoot Date: Fri, 6 Jun 2025 12:17:04 -0400 Subject: implement no-op caches for testing --- packages/backend/src/core/CacheService.ts | 22 ++++++++++++++--- packages/backend/src/misc/cache.ts | 41 ++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 15 deletions(-) (limited to 'packages/backend/src') diff --git a/packages/backend/src/core/CacheService.ts b/packages/backend/src/core/CacheService.ts index ae24a9721f..2c136eac2b 100644 --- a/packages/backend/src/core/CacheService.ts +++ b/packages/backend/src/core/CacheService.ts @@ -28,7 +28,7 @@ export interface CachedTranslation { text: string | undefined; } -interface CachedTranslationEntity { +export interface CachedTranslationEntity { l?: string; t?: string; u?: number; @@ -46,8 +46,8 @@ export class CacheService implements OnApplicationShutdown { public userBlockedCache: QuantumKVCache>; // NOTE: 「被」Blockキャッシュ public renoteMutingsCache: QuantumKVCache>; public userFollowingsCache: QuantumKVCache | undefined>>; - private readonly userFollowStatsCache = new MemoryKVCache(1000 * 60 * 10); // 10 minutes - private readonly translationsCache: RedisKVCache; + protected userFollowStatsCache = new MemoryKVCache(1000 * 60 * 10); // 10 minutes + protected translationsCache: RedisKVCache; constructor( @Inject(DI.redis) @@ -467,6 +467,22 @@ export class CacheService implements OnApplicationShutdown { return users; } + @bindThis + public clear(): void { + this.userByIdCache.clear(); + this.localUserByNativeTokenCache.clear(); + this.localUserByIdCache.clear(); + this.uriPersonCache.clear(); + this.userProfileCache.clear(); + this.userMutingsCache.clear(); + this.userBlockingCache.clear(); + this.userBlockedCache.clear(); + this.renoteMutingsCache.clear(); + this.userFollowingsCache.clear(); + this.userFollowStatsCache.clear(); + this.translationsCache.clear(); + } + @bindThis public dispose(): void { this.internalEventService.off('userChangeSuspendedState', this.onUserEvent); diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 3145550a44..0a1cf6adb4 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -11,9 +11,9 @@ import { InternalEventTypes } from '@/core/GlobalEventService.js'; export class RedisKVCache { private readonly lifetime: number; private readonly memoryCache: MemoryKVCache; - private readonly fetcher: (key: string) => Promise; - private readonly toRedisConverter: (value: T) => string; - private readonly fromRedisConverter: (value: string) => T | undefined; + public readonly fetcher: (key: string) => Promise; + public readonly toRedisConverter: (value: T) => string; + public readonly fromRedisConverter: (value: string) => T | undefined; constructor( private redisClient: Redis.Redis, @@ -101,6 +101,11 @@ export class RedisKVCache { // TODO: イベント発行して他プロセスのメモリキャッシュも更新できるようにする } + @bindThis + public clear() { + this.memoryCache.clear(); + } + @bindThis public gc() { this.memoryCache.gc(); @@ -125,16 +130,17 @@ export class RedisSingleCache { opts: { lifetime: number; memoryCacheLifetime: number; - fetcher: RedisSingleCache['fetcher']; - toRedisConverter: RedisSingleCache['toRedisConverter']; - fromRedisConverter: RedisSingleCache['fromRedisConverter']; + fetcher?: RedisSingleCache['fetcher']; + toRedisConverter?: RedisSingleCache['toRedisConverter']; + fromRedisConverter?: RedisSingleCache['fromRedisConverter']; }, ) { this.lifetime = opts.lifetime; this.memoryCache = new MemorySingleCache(opts.memoryCacheLifetime); - this.fetcher = opts.fetcher; - this.toRedisConverter = opts.toRedisConverter; - this.fromRedisConverter = opts.fromRedisConverter; + + this.fetcher = opts.fetcher ?? (() => { throw new Error('fetch not supported - use get/set directly'); }); + this.toRedisConverter = opts.toRedisConverter ?? ((value) => JSON.stringify(value)); + this.fromRedisConverter = opts.fromRedisConverter ?? ((value) => JSON.parse(value)); } @bindThis @@ -417,6 +423,8 @@ export class MemorySingleCache { } } +// TODO move to separate file + export interface QuantumKVOpts { /** * Memory cache lifetime in milliseconds. @@ -452,9 +460,9 @@ export interface QuantumKVOpts { export class QuantumKVCache implements Iterable<[key: string, value: T]> { private readonly memoryCache: MemoryKVCache; - private readonly fetcher: QuantumKVOpts['fetcher']; - private readonly onSet: QuantumKVOpts['onSet']; - private readonly onDelete: QuantumKVOpts['onDelete']; + public readonly fetcher: QuantumKVOpts['fetcher']; + public readonly onSet: QuantumKVOpts['onSet']; + public readonly onDelete: QuantumKVOpts['onDelete']; /** * @param internalEventService Service bus to synchronize events. @@ -676,6 +684,15 @@ export class QuantumKVCache implements Iterable<[key: string, value: T]> { * Does not send any events or update other processes. */ @bindThis + public clear() { + this.memoryCache.clear(); + } + + /** + * Removes expired cache entries from the local view. + * Does not send any events or update other processes. + */ + @bindThis public gc() { this.memoryCache.gc(); } -- cgit v1.2.3-freya