[STK6-02] 5개 Toss Gateway에 RateLimiter + CircuitBreaker 적용
작업 내용 (설계 의도)
변경 사항
STK6-01의 TossRateLimiterFacade 를 5개 Gateway에 주입하고 각 API 호출을 래핑한다.
기존 retryOn401 패턴은 유지하되 그 외곽을 facade.execute(group) { } 로 감싼다.
401 재시도 자체는 RateLimiter 허용 범위에서 동작하므로 (1회 재시도) 별도 처리 불필요.
변경 대상:
| Gateway | 대상 메서드 | API 그룹 |
|---|---|---|
TossStockPriceGateway | getPrices | MARKET_DATA |
TossStockGatewayImpl | searchStocks, fetchPrices | STOCK, MARKET_DATA |
TossHoldingGateway | fetchHoldings, fetchTradeHistory | ASSET |
TossOrderGateway | placeOrder, correctOrder, cancelOrder | ORDER |
TossAccountGateway | fetchAccounts | ACCOUNT |
TossAuthClient 의 토큰 발급은 캐싱되므로 AUTH 그룹 적용은 선택 사항으로 한다 (실제 HTTP 호출은 드물게 발생).
다이어그램
처리 흐름
sequenceDiagram participant S as Scheduler/UseCase participant G as TossXxxGateway participant F as TossRateLimiterFacade participant T as Toss Open API S->>G: fetchXxx() G->>F: execute(API_GROUP) { retryOn401 { ... } } alt 한도 초과 F-->>G: TossRateLimitException G-->>S: TossRateLimitException else Circuit OPEN F-->>G: TossCircuitOpenException G-->>S: TossCircuitOpenException else 정상 F->>T: RestClient 호출 T-->>F: 200 OK F-->>G: result G-->>S: result end
테스트 케이스
TossStockPriceGateway가TossRateLimiterFacade를MARKET_DATA그룹으로 호출한다TossStockGatewayImpl.searchStocks가TossRateLimiterFacade를STOCK그룹으로 호출한다TossStockGatewayImpl.fetchPrices가TossRateLimiterFacade를MARKET_DATA그룹으로 호출한다TossHoldingGateway.fetchHoldings가TossRateLimiterFacade를ASSET그룹으로 호출한다TossAccountGateway.fetchAccounts가TossRateLimiterFacade를ACCOUNT그룹으로 호출한다TossOrderGateway.placeOrder가TossRateLimiterFacade를ORDER그룹으로 호출한다TossRateLimiterFacade가TossRateLimitException을 throw하면 Gateway도 그대로 전파한다TossRateLimiterFacade가TossCircuitOpenException을 throw하면 Gateway도 그대로 전파한다- 기존 401 재시도 로직이 RateLimiter 허용 범위 내에서 정상 동작한다