Skip to content

Commit 77f92a2

Browse files
authored
한 달에 한 번씩 사용 정보를 초기화한다.
한 달에 한 번씩 사용 정보를 초기화한다.
2 parents 835832b + d08d691 commit 77f92a2

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
}

src/main/kotlin/com/project/codereview/core/repository/GeminiModelStateManager.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ data class ModelState(
2020

2121
@Repository
2222
class GeminiModelStateManager {
23-
2423
private val logger = LoggerFactory.getLogger(GeminiModelStateManager::class.java)
2524
private val modelStates = ConcurrentHashMap<GeminiTextModel, ModelState>()
2625

@@ -55,5 +54,14 @@ class GeminiModelStateManager {
5554
logger.info("[Model UNBLOCKED] {}", model.modelName)
5655
}
5756

57+
fun resetAllToUsable(reason: String = "scheduled-reset") {
58+
val now = Instant.now()
59+
modelStates.forEach { (model, state) ->
60+
state.status = ModelStatus.USABLE
61+
state.blockedUntil = null
62+
}
63+
logger.info("[Model RESET] reason={}, at={}, models={}", reason, now, modelStates.size)
64+
}
65+
5866
fun getAllStates(): Map<GeminiTextModel, ModelState> = modelStates.toMap()
5967
}

0 commit comments

Comments
 (0)