Files
elmprodvpn/selective-vpn-api/app/watchers_runtime.go

99 lines
2.1 KiB
Go

package app
import (
"context"
"strings"
"time"
)
// ---------------------------------------------------------------------
// autoloop watcher
// ---------------------------------------------------------------------
func watchAutoloop(ctx context.Context, every time.Duration) {
lastWord := ""
lastRaw := ""
for {
select {
case <-ctx.Done():
return
case <-time.After(every):
}
lines := tailFile(autoloopLogPath, 200)
word, raw := parseAutoloopStatus(lines)
if word == "" && raw == "" {
continue
}
if word == lastWord && raw == lastRaw {
continue
}
lastWord, lastRaw = word, raw
events.push("autoloop_status_changed", map[string]string{
"status_word": word,
"raw_text": raw,
})
}
}
// ---------------------------------------------------------------------
// systemd unit watcher
// ---------------------------------------------------------------------
func watchSystemdUnit(ctx context.Context, unit string, kind string, every time.Duration) {
last := ""
for {
select {
case <-ctx.Done():
return
case <-time.After(every):
}
stdout, _, _, err := runCommand("systemctl", "is-active", unit)
state := strings.TrimSpace(stdout)
if err != nil || state == "" {
state = "unknown"
}
if state == last {
continue
}
last = state
events.push("unit_state_changed", map[string]string{
"unit": unit,
"kind": kind,
"state": state,
})
}
}
func watchSystemdUnitDynamic(ctx context.Context, resolveUnit func() string, kind string, every time.Duration) {
lastUnit := ""
lastState := ""
for {
select {
case <-ctx.Done():
return
case <-time.After(every):
}
unit := strings.TrimSpace(resolveUnit())
state := "unknown"
if unit != "" {
stdout, _, _, err := runCommand("systemctl", "is-active", unit)
s := strings.TrimSpace(stdout)
if err == nil && s != "" {
state = s
}
}
if unit == lastUnit && state == lastState {
continue
}
lastUnit, lastState = unit, state
events.push("unit_state_changed", map[string]string{
"unit": unit,
"kind": kind,
"state": state,
})
}
}