diff --git a/cmd/gpu-turnstile/monitor.go b/cmd/gpu-turnstile/monitor.go index 365f00b..8153409 100644 --- a/cmd/gpu-turnstile/monitor.go +++ b/cmd/gpu-turnstile/monitor.go @@ -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() } }