feat(health): register LlamaServerHealthProbe (A§4)
Wire the built-but-unregistered LlamaServerHealthProbe (266bbf0) into the health monitor: when a `llamacpp` provider URL is configured, add an HttpLlamaLivenessClient-backed probe (dedicated CIO client, 3s per-ping timeout, shutdown-hook close) to the probe list. Gated on a configured provider URL so a model-less box never reports a spurious LLAMA_SERVER DEGRADED. Replaces the Main.kt TODO(wiring). main() is not unit-tested; the probe + client are already covered by266bbf0— compile + :apps:server:test + detekt green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -96,6 +96,9 @@ import java.nio.file.Paths
|
|||||||
|
|
||||||
private val log = LoggerFactory.getLogger("com.correx.apps.server.Main")
|
private val log = LoggerFactory.getLogger("com.correx.apps.server.Main")
|
||||||
|
|
||||||
|
/** Per-ping timeout (ms) for the llama-server health probe — short so a hung server never stalls it. */
|
||||||
|
private const val LLAMA_HEALTH_TIMEOUT_MS = 3_000L
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
log.info("=== correx server starting ===")
|
log.info("=== correx server starting ===")
|
||||||
log.info(" port : 8080")
|
log.info(" port : 8080")
|
||||||
@@ -438,9 +441,21 @@ fun main() {
|
|||||||
val seeded = DefaultEventReplayer(eventStore, com.correx.apps.server.health.HealthProjection())
|
val seeded = DefaultEventReplayer(eventStore, com.correx.apps.server.health.HealthProjection())
|
||||||
.rebuild(com.correx.apps.server.health.SYSTEM_SESSION)
|
.rebuild(com.correx.apps.server.health.SYSTEM_SESSION)
|
||||||
.subjects.mapValues { it.value.status }
|
.subjects.mapValues { it.value.status }
|
||||||
|
// Monitor the llama server only when a llamacpp provider URL is configured — otherwise the
|
||||||
|
// LLAMA_SERVER subject would report a spurious DEGRADED on a box that runs no local model.
|
||||||
|
// A dedicated short-timeout client keeps a hung server from stalling the probe loop.
|
||||||
|
val llamaProbe = correxConfig.providers.firstOrNull { it.type == "llamacpp" }?.url?.let { url ->
|
||||||
|
val healthHttpClient = io.ktor.client.HttpClient(io.ktor.client.engine.cio.CIO) {
|
||||||
|
engine { requestTimeout = LLAMA_HEALTH_TIMEOUT_MS }
|
||||||
|
}
|
||||||
|
Runtime.getRuntime().addShutdownHook(Thread { healthHttpClient.close() })
|
||||||
|
com.correx.apps.server.health.LlamaServerHealthProbe(
|
||||||
|
com.correx.apps.server.health.HttpLlamaLivenessClient(healthHttpClient, url),
|
||||||
|
)
|
||||||
|
}
|
||||||
com.correx.apps.server.health.HealthMonitor(
|
com.correx.apps.server.health.HealthMonitor(
|
||||||
eventStore = eventStore,
|
eventStore = eventStore,
|
||||||
probes = listOf(
|
probes = listOfNotNull(
|
||||||
com.correx.apps.server.health.DiskWatermarkProbe(
|
com.correx.apps.server.health.DiskWatermarkProbe(
|
||||||
monitoredPaths = listOf(dataDir),
|
monitoredPaths = listOf(dataDir),
|
||||||
warnBytes = hc.diskWarnBytes,
|
warnBytes = hc.diskWarnBytes,
|
||||||
@@ -450,9 +465,7 @@ fun main() {
|
|||||||
eventStore,
|
eventStore,
|
||||||
hc.eventStoreWarnLatencyMs,
|
hc.eventStoreWarnLatencyMs,
|
||||||
),
|
),
|
||||||
// TODO(wiring): register LlamaServerHealthProbe once an HttpClient + tokens/sec telemetry are
|
llamaProbe,
|
||||||
// exposed to the health-monitor scope (currently only built inside
|
|
||||||
// InfrastructureModule.createModelManager).
|
|
||||||
),
|
),
|
||||||
intervalMs = hc.intervalMs,
|
intervalMs = hc.intervalMs,
|
||||||
initialStatuses = seeded,
|
initialStatuses = seeded,
|
||||||
|
|||||||
Reference in New Issue
Block a user