diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2023-03-24 16:43:42 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2023-03-24 16:43:42 +0900 |
| commit | e4380911135b1aff7c85770d6dabb3e72e9874e7 (patch) | |
| tree | 30e1f4ec68d407708e55e612456676c33c048a97 /packages/backend/src/misc/cache.ts | |
| parent | Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop (diff) | |
| download | sharkey-e4380911135b1aff7c85770d6dabb3e72e9874e7.tar.gz sharkey-e4380911135b1aff7c85770d6dabb3e72e9874e7.tar.bz2 sharkey-e4380911135b1aff7c85770d6dabb3e72e9874e7.zip | |
refactor(backend): rename cache class
Diffstat (limited to 'packages/backend/src/misc/cache.ts')
| -rw-r--r-- | packages/backend/src/misc/cache.ts | 89 |
1 files changed, 87 insertions, 2 deletions
diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 43a71a2b57..b249cf4480 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -2,11 +2,11 @@ import { bindThis } from '@/decorators.js'; // TODO: メモリ節約のためあまり参照されないキーを定期的に削除できるようにする? -export class Cache<T> { +export class KVCache<T> { public cache: Map<string | null, { date: number; value: T; }>; private lifetime: number; - constructor(lifetime: Cache<never>['lifetime']) { + constructor(lifetime: KVCache<never>['lifetime']) { this.cache = new Map(); this.lifetime = lifetime; } @@ -87,3 +87,88 @@ export class Cache<T> { return value; } } + +export class Cache<T> { + private cachedAt: number | null = null; + private value: T | undefined; + private lifetime: number; + + constructor(lifetime: Cache<never>['lifetime']) { + this.lifetime = lifetime; + } + + @bindThis + public set(value: T): void { + this.cachedAt = Date.now(); + this.value = value; + } + + @bindThis + public get(): T | undefined { + if (this.cachedAt == null) return undefined; + if ((Date.now() - this.cachedAt) > this.lifetime) { + this.value = undefined; + this.cachedAt = null; + return undefined; + } + return this.value; + } + + @bindThis + public delete() { + this.value = undefined; + this.cachedAt = null; + } + + /** + * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します + * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします + */ + @bindThis + public async fetch(fetcher: () => Promise<T>, validator?: (cachedValue: T) => boolean): Promise<T> { + const cachedValue = this.get(); + if (cachedValue !== undefined) { + if (validator) { + if (validator(cachedValue)) { + // Cache HIT + return cachedValue; + } + } else { + // Cache HIT + return cachedValue; + } + } + + // Cache MISS + const value = await fetcher(); + this.set(value); + return value; + } + + /** + * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します + * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします + */ + @bindThis + public async fetchMaybe(fetcher: () => Promise<T | undefined>, validator?: (cachedValue: T) => boolean): Promise<T | undefined> { + const cachedValue = this.get(); + if (cachedValue !== undefined) { + if (validator) { + if (validator(cachedValue)) { + // Cache HIT + return cachedValue; + } + } else { + // Cache HIT + return cachedValue; + } + } + + // Cache MISS + const value = await fetcher(); + if (value !== undefined) { + this.set(value); + } + return value; + } +} |