Files
Loki/internal/loki/sys_tray_darwin.go
T
MichaelandClaude Opus 5.5 c3005f5b56 Persistance : le fsync de la discussion ne retarde plus le premier token
StartTurn persistait AVANT de lancer la génération : un marshal, puis deux
commits bbolt (contenu, puis index), soit deux fsync et plusieurs ouvertures
de base — 26-30 ms mesurés sur un NVMe Windows, bien plus sur un /mnt/user
d'Unraid ou un disque de parité, payés à chaque message avant que la requête
ne parte vers llama-server. Même facture au milieu d'un tour (vérification du
mode Code) et pour chaque résultat d'outil coupé (« voir plus »).

- chat_persist.go : un écrivain unique et ordonné. L'instantané reste pris
  sous c.mu (images → références, marshal, identifiant de la discussion) ;
  seule l'E/S part en différé. Le dernier instantané de chaque discussion
  l'emporte (numéro pris sous c.mu), les lots sont fusionnés en UNE
  transaction : contenu + index ensemble, résultats d'outils compris.
- Seuls StartTurn, la persistance en cours de tour et les résultats d'outils
  sont asynchrones. Fin de tour, reset, bascules, compactage manuel restent
  synchrones et attendent tout ce qui précède ; la suppression écarte puis
  attend les écritures qui la visent (plus de discussion ressuscitée).
- Discussion active gardée en RAM, créée sous verrou (plus de double
  identifiant sur base neuve) et changée sous c.mu avec le contenu : un
  instantané ne peut plus écrire l'ancien fil sous le nouvel identifiant.
- « Voir plus » servi depuis la mémoire tant que le résultat n'est pas écrit ;
  verrouillage vérifié avant de rendre un id.
- En plein tour, la base reçoit le journal sous sa forme de fin de tour
  (compactLog, version pure de compactLogLocked) ; la mémoire n'est pas touchée.
- Vidage de l'écrivain avant redémarrage, « Quitter », exec et (dé)chiffrement.

Le contexte vu par le modèle ne change pas : il lit c.Messages en mémoire, les
résultats complets d'outils et la compaction du journal ne servent qu'à l'UI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 02:19:03 +02:00

57 lines
2.0 KiB
Go

//go:build darwin
package loki
// sys_tray_darwin.go — icône de Loki dans la barre de menus macOS (en haut à
// droite, à côté de l'horloge), pendant exact du system tray Windows : quand on
// ouvre Loki.app, l'UI web s'ouvre dans le navigateur ET l'icône apparaît, avec
// le menu « Ouvrir Loki » / « Quitter ».
//
// Contrairement à Windows, systray passe ici par Cocoa → CGO obligatoire : les
// binaires macOS sont donc compilés sur un runner macOS (voir release.yml), et
// le bundle est marqué LSUIElement (pas d'icône dans le Dock, uniquement la
// barre de menus).
import (
"os"
"github.com/getlantern/systray"
)
// runTray fait tourner l'icône de la barre de menus. Bloque jusqu'à « Quitter ».
// À appeler depuis la goroutine principale : Cocoa exige le thread main.
func runTray(url string) {
systray.Run(func() {
// Icône « template » : macOS n'en garde que la forme (couche alpha) et la
// colore selon le thème. Indispensable depuis que la marque est noire —
// une icône noire « en dur » est illisible sur une barre de menus sombre.
systray.SetTemplateIcon(brandTemplatePNG(trayIconSize), BrandIconPNG(trayIconSize))
systray.SetTooltip("Loki — votre IA locale")
mOpen := systray.AddMenuItem("Ouvrir Loki", "Ouvrir l'interface")
systray.AddSeparator()
mQuit := systray.AddMenuItem("Quitter", "Arrêter Loki")
go func() {
for {
select {
case <-mOpen.ClickedCh:
_ = openBrowser(url)
case <-mQuit.ClickedCh:
systray.Quit()
return
}
}
}()
}, func() {
// « Quitter » arrête l'application : l'interface et, avec elle, le
// tunnel d'accès distant qui tourne dans ce process.
//
// Le MOTEUR, lui, n'est pas arrêté : sous macOS c'est un daemon launchd,
// que seul root peut piloter. Fermer une interface n'a pas à arrêter un
// service système. Sous Windows, où l'app est propriétaire du moteur,
// « Quitter » l'arrête bel et bien (voir sys_tray_windows.go).
flushPersister(persistExitWait) // écritures différées de la discussion
os.Exit(0)
})
}