/** * 리스크/알림 캐시 서비스 * - 10분마다 자동 갱신 * - 메모리 캐시로 빠른 응답 */ import { RiskAlertService, Alert } from './riskAlertService'; export class RiskAlertCacheService { private static instance: RiskAlertCacheService; private riskAlertService: RiskAlertService; // 메모리 캐시 private cachedAlerts: Alert[] = []; private lastUpdated: Date | null = null; private updateInterval: NodeJS.Timeout | null = null; private constructor() { this.riskAlertService = new RiskAlertService(); } /** * 싱글톤 인스턴스 */ public static getInstance(): RiskAlertCacheService { if (!RiskAlertCacheService.instance) { RiskAlertCacheService.instance = new RiskAlertCacheService(); } return RiskAlertCacheService.instance; } /** * 자동 갱신 시작 (10분 간격) */ public startAutoRefresh(): void { console.log('🔄 리스크/알림 자동 갱신 시작 (10분 간격)'); console.log(' - 기상특보: 즉시 호출'); console.log(' - 교통사고/도로공사: 10분 후 첫 호출'); // 기상특보만 즉시 호출 (ITS API는 10분 후부터) this.refreshWeatherOnly(); // 10분마다 전체 갱신 (600,000ms) this.updateInterval = setInterval(() => { this.refreshCache(); }, 10 * 60 * 1000); } /** * 기상특보만 갱신 (재시작 시 사용) */ private async refreshWeatherOnly(): Promise { try { console.log('🌤️ 기상특보만 즉시 갱신 중...'); const weatherAlerts = await this.riskAlertService.getWeatherAlerts(); this.cachedAlerts = weatherAlerts; this.lastUpdated = new Date(); console.log(`✅ 기상특보 갱신 완료! (${weatherAlerts.length}건)`); } catch (error: any) { console.error('❌ 기상특보 갱신 실패:', error.message); } } /** * 자동 갱신 중지 */ public stopAutoRefresh(): void { if (this.updateInterval) { clearInterval(this.updateInterval); this.updateInterval = null; console.log('⏸️ 리스크/알림 자동 갱신 중지'); } } /** * 캐시 갱신 */ private async refreshCache(): Promise { try { console.log('🔄 리스크/알림 캐시 갱신 중...'); const startTime = Date.now(); const alerts = await this.riskAlertService.getAllAlerts(); this.cachedAlerts = alerts; this.lastUpdated = new Date(); const duration = Date.now() - startTime; console.log(`✅ 리스크/알림 캐시 갱신 완료! (${duration}ms)`); console.log(` - 총 ${alerts.length}건의 알림`); console.log(` - 기상특보: ${alerts.filter(a => a.type === 'weather').length}건`); console.log(` - 교통사고: ${alerts.filter(a => a.type === 'accident').length}건`); console.log(` - 도로공사: ${alerts.filter(a => a.type === 'construction').length}건`); } catch (error: any) { console.error('❌ 리스크/알림 캐시 갱신 실패:', error.message); } } /** * 캐시된 알림 조회 (빠름!) */ public getCachedAlerts(): { alerts: Alert[]; lastUpdated: Date | null } { return { alerts: this.cachedAlerts, lastUpdated: this.lastUpdated, }; } /** * 수동 갱신 (필요 시) */ public async forceRefresh(): Promise { await this.refreshCache(); return this.cachedAlerts; } }