From 64a90e74a9768d055788cc5245697fd05c21f0c2 Mon Sep 17 00:00:00 2001 From: kami Date: Sun, 21 Jun 2026 08:25:25 +0000 Subject: [PATCH] =?UTF-8?q?feat(health):=20register=20LlamaServerHealthPro?= =?UTF-8?q?be=20(A=C2=A74)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 by 266bbf0 — compile + :apps:server:test + detekt green. Co-Authored-By: Claude Opus 4.8 --- .../kotlin/com/correx/apps/server/Main.kt | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt b/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt index ea2cdad8..97ba6a80 100644 --- a/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt +++ b/apps/server/src/main/kotlin/com/correx/apps/server/Main.kt @@ -96,6 +96,9 @@ import java.nio.file.Paths 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() { log.info("=== correx server starting ===") log.info(" port : 8080") @@ -438,9 +441,21 @@ fun main() { val seeded = DefaultEventReplayer(eventStore, com.correx.apps.server.health.HealthProjection()) .rebuild(com.correx.apps.server.health.SYSTEM_SESSION) .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( eventStore = eventStore, - probes = listOf( + probes = listOfNotNull( com.correx.apps.server.health.DiskWatermarkProbe( monitoredPaths = listOf(dataDir), warnBytes = hc.diskWarnBytes, @@ -450,9 +465,7 @@ fun main() { eventStore, hc.eventStoreWarnLatencyMs, ), - // TODO(wiring): register LlamaServerHealthProbe once an HttpClient + tokens/sec telemetry are - // exposed to the health-monitor scope (currently only built inside - // InfrastructureModule.createModelManager). + llamaProbe, ), intervalMs = hc.intervalMs, initialStatuses = seeded,