1+ package com.project.codereview.batch
2+ import com.project.codereview.core.repository.GeminiModelStateManager
3+ import com.project.codereview.core.repository.ModelStatus
4+ import org.slf4j.LoggerFactory
5+ import org.springframework.scheduling.annotation.Scheduled
6+ import org.springframework.stereotype.Component
7+
8+ @Component
9+ class GeminiModelScheduler (
10+ private val modelStateManager : GeminiModelStateManager
11+ ) {
12+ private val logger = LoggerFactory .getLogger(javaClass)
13+
14+ @Scheduled(cron = " 0 0 0 1 * *" , zone = " Asia/Seoul" )
15+ fun resetAllModelsToUsable () {
16+ logger.info(" [Scheduler] Monthly model reset triggered" )
17+ modelStateManager.resetAllToUsable(reason = " monthly-1st" )
18+ }
19+
20+ // 매시간 0분 0초에 실행 (KST)
21+ @Scheduled(cron = " 0 0 * * * *" , zone = " Asia/Seoul" )
22+ fun logAllStatesHourly () {
23+ val states = modelStateManager.getAllStates()
24+
25+ val usable = states.values.count { it.status == ModelStatus .USABLE }
26+ val blocked = states.values.count { it.status == ModelStatus .BLOCKED }
27+
28+ logger.info(
29+ " [Batch] Hourly model states - total={}, usable={}, blocked={}" ,
30+ states.size, usable, blocked
31+ )
32+
33+ // 모델별 상태도 필요하면 아래 로그를 켜서 확인
34+ states.values
35+ .sortedBy { it.model.modelName }
36+ .forEach { state ->
37+ logger.info(
38+ " [Batch] model={}, status={}, blockedUntil={}" ,
39+ state.model.modelName, state.status, state.blockedUntil
40+ )
41+ }
42+ }
43+ }
0 commit comments