From f1cf9610f490065819fb95dbd195c985e455883e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9C=A4=EC=A0=95=EB=AF=BC?= Date: Tue, 14 Apr 2026 23:13:34 +0900 Subject: [PATCH] Document the in-memory caching strategy for KBO game list data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 게임 리스트 조회 시 Firestore 공유 캐시 대신 인스턴스 단위 인메모리 캐시를 사용하는 기술적 근거를 상세히 기록했습니다. - 실시간 경기 중 빈번한 데이터 변경으로 인한 Firestore 비용 부담과 레이턴시 문제를 해결하기 위한 결정임을 명시했습니다. - 향후 트래픽 증가나 외부 API의 일시적인 503 오류 등 서비스 안정성에 영향을 줄 수 있는 상황에 대비하여, 공유 캐시로의 격상 검토안을 TODO에 추가했습니다. --- TODO.md | 6 ++++++ src/services/gameListService.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/TODO.md b/TODO.md index d868440..de7802e 100644 --- a/TODO.md +++ b/TODO.md @@ -23,6 +23,12 @@ - 현재는 `npm run build` 빠뜨리면 구버전 `lib/` 그대로 배포됨 ### 향후 확장 여지 +- [ ] **GameList 캐시를 Firestore 공유 캐시로 격상 검토** + - 현재: `gameListService.ts`의 10초 메모리 캐시 (인스턴스별) + - 트래픽 증가 시 인스턴스 수 × (6회/분)로 KBO 호출 증가 → rate limit 리스크 + - 격상안: `kboCacheRepository.getOrFetch` 사용, 키 `gameList_day__YYYYMMDD__series`, TTL은 스케줄과 동일한 동적(라이브 30s, 종료 7d) 방식 + - 지금은 불필요. 트래픽/에러율 지표 보고 결정 + - [ ] 라이브 상세 필드 별도 엔드포인트로 노출 - 이닝/카운트/주자/현재 타자·투수는 "스케줄 파악" 목적에서 제외했으나, 라이브 상세 화면 필요 시 `getGameList` 직접 노출하는 별도 핸들러 추가 고려 - [ ] `formatYmd(new Date())` → `todayKst()` 기반으로 통일 diff --git a/src/services/gameListService.ts b/src/services/gameListService.ts index 9f65782..a5a5220 100644 --- a/src/services/gameListService.ts +++ b/src/services/gameListService.ts @@ -6,6 +6,18 @@ import { type GameListResult, } from "../kbo/game-list.js"; +// 게임센터(GetKboGameList)는 다른 KBO 데이터와 달리 Firestore 공유 캐시 +// (kboCacheRepository) 대신 인스턴스 단위 인메모리 캐시를 쓴다. +// +// 이유: +// - 라이브 경기 중에는 초 단위로 값이 바뀌므로 긴 TTL을 둘 수 없다. 현실적인 +// TTL(10초)에선 Firestore read/write 비용이 KBO 직접 호출 비용을 금방 넘어선다. +// - schedule 머지 경로에서 매 요청마다 호출되기 때문에 Firestore 왕복 레이턴시 +// (수십 ms)를 응답 시간에 그대로 얹게 된다. +// - 인스턴스별 중복 호출은 있지만, 인스턴스당 최대 6회/분이라 KBO 측 부담은 낮다. +// +// 트래픽이 커져 인스턴스 수 × 호출량이 문제가 되면 Firestore 공유 캐시로 +// 격상을 재검토 (TODO.md 참조). const MEM_TTL_MS = 10_000; const MEM_MAX = 100;