moex-vibe/apps/backend/src/modules/cache/cache.service.ts

45 lines
1.3 KiB
TypeScript

import { Injectable, Inject } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class CacheService {
constructor(
@Inject(CACHE_MANAGER) private cacheManager: Cache,
private configService: ConfigService,
) {}
async get<T>(key: string): Promise<T | undefined> {
return this.cacheManager.get<T>(key);
}
async set(key: string, value: unknown, ttl?: number): Promise<void> {
await this.cacheManager.set(key, value, ttl);
}
private buildKey(...parts: string[]): string {
return parts.join(':');
}
async getOrFetch<T>(
keyPrefix: string,
keyParts: string[],
fetchFn: () => Promise<T>,
ttlConfigKey: string,
): Promise<{ data: T; fromCache: boolean; cachedAt: string | null }> {
const key = this.buildKey(keyPrefix, ...keyParts);
const ttl = this.configService.get<number>(`app.cache.${ttlConfigKey}`, 900);
const cached = await this.get<T>(key);
if (cached !== undefined) {
return { data: cached, fromCache: true, cachedAt: null };
}
const data = await fetchFn();
await this.set(key, data, ttl);
return { data, fromCache: false, cachedAt: new Date().toISOString() };
}
}