Monitor: add r hotkey for config reload

Generalizes the one-shot ask behind u into a shared helper; r sends
reload-env and reports the service's reply (unchanged / restarting with
the changed setting names / invalid config) in the note line. Footer now
lists q, u, r.
This commit is contained in:
mram
2026-09-22 13:33:46 +02:00
parent a07b6726ea
commit 2040b30c94
+28 -18
View File
@@ -22,13 +22,14 @@ const (
)
// hotkeysLine is the monitor's footer.
const hotkeysLine = " " + cDim + "q quit · u update now" + cReset + "\x1b[K\n"
const hotkeysLine = " " + cDim + "q quit · u update now · r reload config" + cReset + "\x1b[K\n"
// monitorCommand renders a live status view of the running service,
// refreshed every second from the control channel. When the service
// reports a different version and the executable on disk changed (the
// updater replaced it), the monitor restarts itself onto the new binary.
// Hotkeys: q quits, u triggers an update check on the service.
// Hotkeys: q quits, u triggers an update check on the service, r asks the
// service to reload its config file.
func monitorCommand() int {
if !stdoutIsTerminal() {
fmt.Fprintln(os.Stderr, "gpu-turnstile: --monitor needs an interactive terminal")
@@ -57,7 +58,27 @@ func monitorCommand() int {
var note string
var noteAt time.Time
noteCh := make(chan string, 1)
updatePending := false
askPending := false
// ask sends a one-shot command to the service and reports the reply in
// the note line. Only one ask runs at a time.
ask := func(cmd, busy, label string) {
if askPending {
return
}
askPending = true
note, noteAt = busy, time.Now()
go func() {
reply, err := control.Ask(cmd)
if err != nil {
noteCh <- label + ": no answer from the service"
return
}
msg := strings.TrimPrefix(reply, "OK ")
msg = strings.TrimPrefix(msg, "ERR ")
noteCh <- label + ": " + msg
}()
}
poll := func() string {
frame := renderWaiting()
@@ -104,23 +125,12 @@ func monitorCommand() int {
case 'q', 'Q', 3: // q or Ctrl+C (raw mode delivers it as a byte)
return 0
case 'u', 'U':
if !updatePending {
updatePending = true
note, noteAt = "checking for updates…", time.Now()
go func() {
reply, err := control.Ask(control.CmdUpdateNow)
if err != nil {
noteCh <- "update: no answer from the service"
return
}
msg := strings.TrimPrefix(reply, "OK ")
msg = strings.TrimPrefix(msg, "ERR ")
noteCh <- "update: " + msg
}()
}
ask(control.CmdUpdateNow, "checking for updates…", "update")
case 'r', 'R':
ask(control.CmdReloadEnv, "reloading config…", "reload")
}
case n := <-noteCh:
updatePending = false
askPending = false
note, noteAt = n, time.Now()
}
}