feat: correx-managed model lifecycle slice 4 — resource telemetry
Vendor-agnostic ResourceProbe (commons): NvidiaResourceProbe reads nvidia-smi (injectable runner) for whole-device VRAM/util and /proc/<pid>/status for the managed llama-server RSS, both fail-soft to null; UnavailableProbe for non-GPU hosts / the static path. DefaultModelManager.currentPid() + LlamaProcess.pid expose the managed pid. ServerMessage.ResourceStatus (resource.status, NonEventMessage, all-nullable) pushed every 2.5s on the global stream plus one in the initial snapshot. Live gauge only — never event-sourced (feeds no core decision), so invariants #8/#9 hold. Main wires the NVIDIA probe on the managed path when nvidia-smi is present, else UnavailableProbe. Tests: csv parsing (single/multi/malformed), gpu+rss combine, fallbacks. Plan: docs/plans/2026-05-31-model-lifecycle-management.md (slice 4 of 5).
This commit is contained in:
+7
@@ -129,6 +129,13 @@ class DefaultModelManager(
|
||||
|
||||
override fun currentModel(): ModelDescriptor? = currentDescriptor
|
||||
|
||||
/**
|
||||
* The managed `llama-server` OS pid, or null when no model is resident. Read without the mutex
|
||||
* for the live resource gauge — a stale/null read for one probe tick during a swap is acceptable
|
||||
* (telemetry only, feeds no core decision).
|
||||
*/
|
||||
fun currentPid(): Long? = currentProcess?.pid
|
||||
|
||||
override fun healthCheck(): ProviderHealth {
|
||||
val process = currentProcess ?: return ProviderHealth.Unavailable("No model loaded")
|
||||
return if (process.isAlive) {
|
||||
|
||||
+4
@@ -16,6 +16,10 @@ class LlamaProcess(
|
||||
val isAlive: Boolean
|
||||
get() = process?.isAlive ?: false
|
||||
|
||||
/** The OS pid of the running process, or null when not started / not alive. */
|
||||
val pid: Long?
|
||||
get() = process?.takeIf { it.isAlive }?.pid()
|
||||
|
||||
suspend fun start() = withContext(Dispatchers.IO) {
|
||||
if (isAlive) return@withContext
|
||||
|
||||
|
||||
Reference in New Issue
Block a user