ERP-node/backend-node/src/utils/cache.ts

144 lines
2.9 KiB
TypeScript
Raw Normal View History

2025-09-08 14:20:01 +09:00
/**
*
*
*/
interface CacheItem<T> {
data: T;
timestamp: number;
ttl: number; // Time to live in milliseconds
}
class MemoryCache {
private cache = new Map<string, CacheItem<any>>();
private readonly DEFAULT_TTL = 5 * 60 * 1000; // 5분
/**
*
*/
set<T>(key: string, data: T, ttl: number = this.DEFAULT_TTL): void {
this.cache.set(key, {
data,
timestamp: Date.now(),
ttl,
});
}
/**
*
*/
get<T>(key: string): T | null {
const item = this.cache.get(key);
if (!item) {
return null;
}
// TTL 체크
if (Date.now() - item.timestamp > item.ttl) {
this.cache.delete(key);
return null;
}
return item.data as T;
}
/**
*
*/
delete(key: string): boolean {
return this.cache.delete(key);
}
/**
* ( )
*/
deleteByPattern(pattern: string): number {
let deletedCount = 0;
const regex = new RegExp(pattern);
for (const key of this.cache.keys()) {
if (regex.test(key)) {
this.cache.delete(key);
deletedCount++;
}
}
return deletedCount;
}
/**
*
*/
cleanup(): number {
let cleanedCount = 0;
const now = Date.now();
for (const [key, item] of this.cache.entries()) {
if (now - item.timestamp > item.ttl) {
this.cache.delete(key);
cleanedCount++;
}
}
return cleanedCount;
}
/**
*
*/
getStats(): {
totalKeys: number;
expiredKeys: number;
memoryUsage: string;
} {
const now = Date.now();
let expiredKeys = 0;
for (const item of this.cache.values()) {
if (now - item.timestamp > item.ttl) {
expiredKeys++;
}
}
return {
totalKeys: this.cache.size,
expiredKeys,
memoryUsage: `${Math.round(JSON.stringify([...this.cache.entries()]).length / 1024)} KB`,
};
}
/**
*
*/
clear(): void {
this.cache.clear();
}
}
// 싱글톤 인스턴스
export const cache = new MemoryCache();
// 캐시 키 생성 헬퍼
export const CacheKeys = {
TABLE_LIST: "table_list",
TABLE_COLUMNS: (tableName: string, page: number, size: number) =>
`table_columns:${tableName}:${page}:${size}`,
TABLE_COLUMN_COUNT: (tableName: string) => `table_column_count:${tableName}`,
WEB_TYPE_OPTIONS: "web_type_options",
COMMON_CODES: (category: string) => `common_codes:${category}`,
} as const;
// 자동 정리 스케줄러 (10분마다)
setInterval(
() => {
const cleaned = cache.cleanup();
if (cleaned > 0) {
console.log(`[Cache] 만료된 캐시 ${cleaned}개 정리됨`);
}
},
10 * 60 * 1000
);
export default cache;