83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import { cacheConfig } from "../config/cache.js";
|
|
import { cacheHits, cacheMisses } from "../monitoring/metrics.js";
|
|
import { logCacheHit, logCacheMiss } from "../monitoring/logger.js";
|
|
import { RedisCache } from "./redisCache.js";
|
|
|
|
/**
|
|
* Cache-Interface für Abstraktion
|
|
*/
|
|
export interface CacheInterface<T> {
|
|
set(key: string, data: T, ttl?: number): void | Promise<void>;
|
|
get(key: string): T | null | Promise<T | null>;
|
|
clear(): void | Promise<void>;
|
|
delete(key: string): void | Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* In-Memory Cache (Fallback wenn Redis nicht verfügbar)
|
|
*/
|
|
class InMemoryCache<T> implements CacheInterface<T> {
|
|
private cache = new Map<string, { data: T; expiresAt: number }>();
|
|
private defaultTTL: number;
|
|
private cacheType: string;
|
|
|
|
constructor(defaultTTL: number, cacheType: string) {
|
|
this.defaultTTL = defaultTTL;
|
|
this.cacheType = cacheType;
|
|
}
|
|
|
|
async set(key: string, data: T, ttl?: number): Promise<void> {
|
|
const expiresAt = Date.now() + (ttl || this.defaultTTL);
|
|
this.cache.set(key, { data, expiresAt });
|
|
}
|
|
|
|
async get(key: string): Promise<T | null> {
|
|
const entry = this.cache.get(key);
|
|
if (!entry) {
|
|
cacheMisses.inc({ cache_type: this.cacheType });
|
|
logCacheMiss(key, this.cacheType);
|
|
return null;
|
|
}
|
|
|
|
if (Date.now() > entry.expiresAt) {
|
|
this.cache.delete(key);
|
|
cacheMisses.inc({ cache_type: this.cacheType });
|
|
logCacheMiss(key, this.cacheType);
|
|
return null;
|
|
}
|
|
|
|
cacheHits.inc({ cache_type: this.cacheType });
|
|
logCacheHit(key, this.cacheType);
|
|
return entry.data;
|
|
}
|
|
|
|
async clear(): Promise<void> {
|
|
this.cache.clear();
|
|
}
|
|
|
|
async delete(key: string): Promise<void> {
|
|
this.cache.delete(key);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Cache-Instanzen
|
|
* Verwendet Redis wenn aktiviert, sonst In-Memory
|
|
*/
|
|
const useRedis = process.env["REDIS_ENABLED"] === "true";
|
|
|
|
export const cache = {
|
|
pages: useRedis
|
|
? new RedisCache<any>(cacheConfig.pages.ttl, "pages")
|
|
: new InMemoryCache<any>(cacheConfig.pages.ttl, "pages"),
|
|
pageSeo: useRedis
|
|
? new RedisCache<any>(cacheConfig.pageSeo.ttl, "pageSeo")
|
|
: new InMemoryCache<any>(cacheConfig.pageSeo.ttl, "pageSeo"),
|
|
navigation: useRedis
|
|
? new RedisCache<any>(cacheConfig.navigation.ttl, "navigation")
|
|
: new InMemoryCache<any>(cacheConfig.navigation.ttl, "navigation"),
|
|
products: useRedis
|
|
? new RedisCache<any>(cacheConfig.products.ttl, "products")
|
|
: new InMemoryCache<any>(cacheConfig.products.ttl, "products"),
|
|
};
|