mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-23 15:08:16 +02:00
Moniteur : corrections de relecture — un nvidia-smi pendu ne fige plus les jauges
gpuStatsCached tient son verrou pendant la requête : c'est ce qui fait partager une seule lecture aux onglets. Mais la requête n'était pas bornée, et le code le dit ailleurs (nvidiaGPUCount) : un pilote coincé peut faire pendre nvidia-smi. Avant le cache, chaque nouvelle requête relançait son propre nvidia-smi et les jauges revenaient avec le pilote ; avec le verrou, un seul processus pendu bloquait /api/vram pour tous les onglets jusqu'au redémarrage de Loki. - nvidiaSmiQuery : CommandContext borné à 10 s (large pour une première lecture lente sans mode persistant), WaitDelay d'une seconde. Au-delà, une erreur ordinaire, retentée au délai normal du cache. - Le déchargement profite de la même borne : une lecture pendue devient une mesure ratée, que gpuSettle sait déjà sauter. - Test : la vraie requête, binaire absent du PATH, rend bien exec.ErrNotFound — la seule erreur que le cache garde une minute. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4f34694400
commit
9b2e974942
2 files changed
+27
-2
No files matched your search
@@ -13,6 +13,7 @@
|
|||||||
package loki
|
package loki
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -36,12 +37,25 @@ type gpuStat struct {
|
|||||||
|
|
||||||
// nvidiaSmiQuery lance la requête nvidia-smi. Variable pour que les tests
|
// nvidiaSmiQuery lance la requête nvidia-smi. Variable pour que les tests
|
||||||
// substituent un faux exécutable et comptent les lancements.
|
// substituent un faux exécutable et comptent les lancements.
|
||||||
|
//
|
||||||
|
// Bornée dans le temps, comme nvidiaGPUCount : un pilote coincé peut faire
|
||||||
|
// pendre nvidia-smi, et gpuStatsCached tient son verrou pendant la requête. Sans
|
||||||
|
// borne, un seul nvidia-smi pendu figeait les jauges de TOUS les onglets
|
||||||
|
// jusqu'au redémarrage de Loki, même une fois le pilote revenu. Dix secondes :
|
||||||
|
// large pour une première lecture lente (pilote sans mode persistant, plusieurs
|
||||||
|
// cartes), une erreur ordinaire au-delà — retentée au délai normal.
|
||||||
var nvidiaSmiQuery = func() ([]byte, error) {
|
var nvidiaSmiQuery = func() ([]byte, error) {
|
||||||
return hideCmd(exec.Command("nvidia-smi",
|
ctx, cancel := context.WithTimeout(context.Background(), nvidiaSmiTimeout)
|
||||||
|
defer cancel()
|
||||||
|
cmd := hideCmd(exec.CommandContext(ctx, "nvidia-smi",
|
||||||
"--query-gpu=name,memory.used,memory.total,utilization.gpu,temperature.gpu",
|
"--query-gpu=name,memory.used,memory.total,utilization.gpu,temperature.gpu",
|
||||||
"--format=csv,noheader,nounits")).Output()
|
"--format=csv,noheader,nounits"))
|
||||||
|
cmd.WaitDelay = time.Second // un descendant qui garderait la sortie ouverte ne retient pas Wait
|
||||||
|
return cmd.Output()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const nvidiaSmiTimeout = 10 * time.Second
|
||||||
|
|
||||||
// gpuStats interroge nvidia-smi. Renvoie nil quand il est absent (machine sans
|
// gpuStats interroge nvidia-smi. Renvoie nil quand il est absent (machine sans
|
||||||
// GPU NVIDIA, Mac, CPU seul) : l'absence de mesure n'est pas une erreur, elle
|
// GPU NVIDIA, Mac, CPU seul) : l'absence de mesure n'est pas une erreur, elle
|
||||||
// prive juste le déchargement de son bilan chiffré. Toujours une lecture
|
// prive juste le déchargement de son bilan chiffré. Toujours une lecture
|
||||||
|
|||||||
@@ -170,3 +170,14 @@ func TestGpuSettleSampleFrais(t *testing.T) {
|
|||||||
t.Errorf("jauges : %d, attendu la lecture en cache 19000", g[0].Used)
|
t.Errorf("jauges : %d, attendu la lecture en cache 19000", g[0].Used)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Le cache ne mémorise une minute que l'ABSENCE de nvidia-smi : il faut donc que
|
||||||
|
// la vraie requête (bornée dans le temps) rende toujours exec.ErrNotFound quand
|
||||||
|
// le binaire n'est pas dans le PATH — sinon Mac et CPU seul relanceraient une
|
||||||
|
// recherche toutes les deux secondes.
|
||||||
|
func TestNvidiaSmiQueryAbsent(t *testing.T) {
|
||||||
|
t.Setenv("PATH", t.TempDir())
|
||||||
|
if _, err := nvidiaSmiQuery(); !errors.Is(err, exec.ErrNotFound) {
|
||||||
|
t.Fatalf("erreur %v, attendu exec.ErrNotFound", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user