mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-18 04:36:44 +02:00
Lot 16 : pilotage du moteur tenu par la façade (LOKI_ENGINE=rust)
La façade sert /api/start, /api/stop, /api/restart, /api/vram/unload et /api/vram/reload quand LOKI_ENGINE=rust (expérimental ; le Go reste le défaut). Elle lance elle-même « loki-rs engine <action> », le superviseur que le Go appelait déjà en conteneur, avec l'environnement qu'il lui passait et de quoi joindre l'API interne du Go ; sa dernière ligne d'erreur devient l'erreur rendue. Le contrôle d'avant démarrage (preflightEngine : preset externe, Strata, BIN, MODEL, tranches) et le bilan de VRAM du déchargement (gpuSettle) sont portés. La façade ne tient ce lot qu'en conteneur : sous systemd ou avec LOKI_ENGINE_SUPERVISOR=go, loki-rs ne passe pas la variable au Go. Restent au Go derrière son API interne (facade_engine.go) : le verrou de l'optimiseur avant tout démarrage (/internal/v1/service/prestart), la réponse en cours quand il tient la conversation (/internal/v1/chat/generating) et l'arrêt de la dictée quand il la tient (/internal/v1/dictate/stop). Parité : parity_engine_test.go tire du Go dix bilans de VRAM, vingt-six installations passées au préflight, les messages du superviseur et dix réponses de route, rejoués par tests/enginectl.rs ; démarrage, arrêt, redémarrage, déchargement chiffré et rechargement vérifiés de bout en bout avec un faux superviseur et un faux nvidia-smi ; TestFacadeMoteur côté Go. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
19 files changed
+2225
-2
No files matched your search
@@ -0,0 +1,90 @@
|
||||
package loki
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// facade_engine.go — pilotage du moteur tenu par la façade Rust
|
||||
// (LOKI_ENGINE=rust, lot 16 de la migration ; expérimental, le Go reste le
|
||||
// défaut) : démarrage, arrêt, redémarrage (/api/start|stop|restart) et
|
||||
// déchargement / rechargement de la VRAM (/api/vram/unload|reload).
|
||||
//
|
||||
// La façade lance elle-même « loki-rs engine <action> » — le superviseur que
|
||||
// le Go appelait déjà en conteneur (sys_service_rust_linux.go) — et contrôle
|
||||
// le moteur avant de le relancer (preflightEngine). Elle ne tient ce lot qu'en
|
||||
// conteneur avec ce superviseur : sous systemd, ou avec
|
||||
// LOKI_ENGINE_SUPERVISOR=go, le Go le garde (décidé par loki-rs au démarrage).
|
||||
//
|
||||
// Ce qui vit ici reste ici jusqu'au lot qui le portera, derrière l'API
|
||||
// interne :
|
||||
//
|
||||
// - le verrou de l'optimiseur, consulté puis débarrassé d'un essai orphelin
|
||||
// avant tout démarrage (/internal/v1/service/prestart) ;
|
||||
// - la génération en cours quand le Go tient la conversation
|
||||
// (/internal/v1/chat/generating) ;
|
||||
// - l'arrêt de la dictée quand le Go la tient (/internal/v1/dictate/stop).
|
||||
|
||||
const facadeEngineEnv = "LOKI_ENGINE"
|
||||
|
||||
// facadeEngine : la façade pilote-t-elle le moteur ?
|
||||
func facadeEngine() bool {
|
||||
return strings.EqualFold(strings.TrimSpace(os.Getenv(facadeEngineEnv)), "rust") &&
|
||||
facadeAddr() != "" && internalToken() != ""
|
||||
}
|
||||
|
||||
// facadeEngineRoutes : les routes que la façade sert alors (enginectl.rs).
|
||||
var facadeEngineRoutes = map[string]bool{
|
||||
"/api/start": true,
|
||||
"/api/stop": true,
|
||||
"/api/restart": true,
|
||||
"/api/vram/unload": true,
|
||||
"/api/vram/reload": true,
|
||||
}
|
||||
|
||||
// enginePrestart : ce que serviceAction fait avant un démarrage — refus
|
||||
// pendant une optimisation, puis ménage d'un verrou périmé (essai orphelin
|
||||
// arrêté, application interrompue défaite). Variable pour les tests.
|
||||
var enginePrestart = func() error {
|
||||
if err := tuneGuard(); err != nil {
|
||||
return err
|
||||
}
|
||||
tuneReapStale()
|
||||
return nil
|
||||
}
|
||||
|
||||
// handleInternalServicePrestart : POST → 200 {error} ("" : la voie est
|
||||
// libre).
|
||||
func handleInternalServicePrestart(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
sendJSON(w, http.StatusMethodNotAllowed, map[string]any{"error": "POST attendu"})
|
||||
return
|
||||
}
|
||||
msg := ""
|
||||
if err := enginePrestart(); err != nil {
|
||||
msg = err.Error()
|
||||
}
|
||||
sendJSON(w, http.StatusOK, map[string]any{"error": msg})
|
||||
}
|
||||
|
||||
// handleInternalChatGenerating : GET → 200 {generating} — la conversation
|
||||
// tenue ici écrit-elle une réponse ?
|
||||
func handleInternalChatGenerating(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
sendJSON(w, http.StatusMethodNotAllowed, map[string]any{"error": "GET attendu"})
|
||||
return
|
||||
}
|
||||
sendJSON(w, http.StatusOK, map[string]any{"generating": conv.isGenerating()})
|
||||
}
|
||||
|
||||
// handleInternalDictateStop : POST → 204 — arrête la dictée tenue ici, sans
|
||||
// attendre derrière un démarrage (asrShutdownVite).
|
||||
func handleInternalDictateStop(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
sendJSON(w, http.StatusMethodNotAllowed, map[string]any{"error": "POST attendu"})
|
||||
return
|
||||
}
|
||||
asrShutdownVite()
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
Reference in new issue
Block a user