[STK4-03] 가격 캐시 엔티티·30초 스케줄러

작업 내용 (설계 의도)

변경 사항

StockPriceCache Entity, StockPriceCacheRepository interface, StockPriceScheduler(@Scheduled(fixedDelay=30_000))를 구현한다. 스케줄러는 토스 API 배치 조회 → stock_price_cache 갱신 → SseEmitterRegistry에 push 순서로 동작한다. SseEmitterRegistry도 이 티켓에서 구현한다(emitter 등록·해제·timeout 관리).

선행: STK4-01

다이어그램

처리 흐름

sequenceDiagram
    participant Sched as StockPriceScheduler
    participant Toss as TossStockGateway
    participant Cache as StockPriceCacheRepository
    participant Registry as SseEmitterRegistry

    loop 30초마다
        Sched->>Toss: fetchPrices(allSymbols)
        Toss-->>Sched: List<TossPriceDto>
        Sched->>Cache: upsertAll(prices)
        Sched->>Registry: broadcast(prices)
    end

클래스 의존

flowchart LR
    StockPriceScheduler --> SyncStocksUseCase
    StockPriceScheduler --> SseEmitterRegistry
    SyncStocksUseCase --> StockDomainService
    StockPriceCacheRepositoryImpl -.->|implements| StockPriceCacheRepository

테스트 케이스

  • @Scheduled(fixedDelay=30_000) 트리거 시 토스 API를 호출하고 캐시를 갱신한다
  • 캐시 갱신 후 SseEmitterRegistry.broadcast()가 호출된다
  • SseEmitterRegistry에 emitter 등록 후 timeout 만료 시 자동 제거된다
  • 토스 API 5xx 응답 시 예외를 삼키고 WARN 로그를 출력한다 (스케줄러 중단 방지)
  • SseEmitterRegistry emitter 해제 후 broadcast에서 해당 emitter를 제외한다