mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-11 17:26:57 +02:00
Démarrage, captures, postes distants : correctifs portés d'AJEAN
- Au démarrage, une lecture ratée de la base (verrou bbolt transitoire pendant le chevauchement des process au redémarrage du conteneur) était confondue avec une conversation absente. Pire que l'amont chez nous : getStr rend "" dans les deux cas, donc convEnsureActive forgeait un NOUVEL identifiant et l'écrasait — le fil en cours devenait orphelin, en silence. On sonde désormais la base avec son erreur AVANT toute écriture, on réessaie quatre fois, et un échec durable est journalisé sans que rien ne soit touché. - Une capture d'écran disparaissait sans laisser de trace : stripImageParts aplatissait le message en ne gardant que sa légende. Le marqueur imageLostMarker rend la perte VISIBLE, pour que le modèle sache reprendre une capture au lieu de la redécrire de mémoire. - maxLogEvents 20000 → 200000 : un seul tour à très long raisonnement tronquait déjà le journal de rejeu, et l'utilisateur perdait le début de sa conversation à l'écran. - Keepalive WebSocket des postes distants (ping toutes les 25 s, des DEUX côtés). Sans lui, un poste au repos était coupé au bout de ~60-100 s par les intermédiaires qui ferment les canaux inactifs, puis reconnecté après backoff — les déconnexions à répétition sur tous les postes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2d4f5378c0
commit
c45ba615fa
6 files changed
+308
-11
No files matched your search
@@ -36,6 +36,13 @@ const (
|
||||
maxTimeoutSec = 300
|
||||
maxOutput = 8000 // caractères de stdout/stderr renvoyés
|
||||
readMax = 100000 // caractères max d'une lecture de fichier
|
||||
// nodePingInterval : cadence du keepalive WebSocket. 25 s tient sous les délais
|
||||
// d'inactivité usuels des proxys et relais (~60-100 s). Doit rester alignée sur
|
||||
// la constante homonyme côté serveur (node_server.go).
|
||||
nodePingInterval = 25 * time.Second
|
||||
// nodePingTimeout : au-delà, le serveur ne répond plus — on ferme, et Run
|
||||
// reconnecte proprement au lieu de garder une connexion morte.
|
||||
nodePingTimeout = 10 * time.Second
|
||||
)
|
||||
|
||||
// Config persiste l'appairage et les préférences locales du poste.
|
||||
@@ -245,6 +252,32 @@ func session(ctx context.Context, cfg Config, quiet bool) error {
|
||||
if !quiet {
|
||||
fmt.Printf("[node] connecté ✓ (canal chiffré, en attente des demandes de l'IA)\n")
|
||||
}
|
||||
// Keepalive : un ping WebSocket périodique empêche les intermédiaires (relais,
|
||||
// Caddy, Cloudflare) de couper la connexion quand l'IA ne sollicite pas le
|
||||
// poste. Sans lui, un canal inactif tombait au bout de ~60-100 s, la session se
|
||||
// terminait et Run reconnectait après backoff — d'où les déconnexions à
|
||||
// répétition sur tous les postes. coder/websocket sérialise Ping avec les
|
||||
// écritures de données : pas de course avec sendEnc.
|
||||
pingCtx, stopPing := context.WithCancel(ctx)
|
||||
defer stopPing()
|
||||
go func() {
|
||||
t := time.NewTicker(nodePingInterval)
|
||||
defer t.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-pingCtx.Done():
|
||||
return
|
||||
case <-t.C:
|
||||
pc, cancel := context.WithTimeout(pingCtx, nodePingTimeout)
|
||||
err := c.Ping(pc)
|
||||
cancel()
|
||||
if err != nil {
|
||||
_ = c.Close(websocket.StatusGoingAway, "ping sans réponse")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
for {
|
||||
var fr nodewire.Frame
|
||||
if err := wsjson.Read(ctx, c, &fr); err != nil {
|
||||
|
||||
Reference in new issue
Block a user