chore: release v0.11.2
This commit is contained in:
+51
-19
@@ -42,6 +42,7 @@ func (a *App) SetLiveStatusEnabled(on bool) error {
|
||||
return err
|
||||
}
|
||||
if on {
|
||||
applog.Printf("livestatus: enabled (logbook backend=%q, mysql conn=%v)", a.dbBackend, a.logDb != nil)
|
||||
go a.publishLiveStatus() // show up right away
|
||||
} else {
|
||||
a.clearLiveStatus()
|
||||
@@ -52,16 +53,13 @@ func (a *App) SetLiveStatusEnabled(on bool) error {
|
||||
// liveStatusLoop heartbeats the current activity while enabled. Started once at
|
||||
// startup; cheap no-op when disabled or not on MySQL.
|
||||
func (a *App) liveStatusLoop() {
|
||||
defer func() { _ = recover() }() // never crash the app from here
|
||||
applog.Printf("livestatus: loop started")
|
||||
a.publishLiveStatus() // attempt immediately, don't wait the first tick
|
||||
t := time.NewTicker(15 * time.Second)
|
||||
defer t.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-a.ctx.Done():
|
||||
a.clearLiveStatus()
|
||||
return
|
||||
case <-t.C:
|
||||
a.publishLiveStatus()
|
||||
}
|
||||
for range t.C {
|
||||
a.publishLiveStatus()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,28 +69,47 @@ func (a *App) liveStatusActive() bool {
|
||||
}
|
||||
|
||||
// liveStatusOperator returns this instance's operator id (the operator callsign,
|
||||
// falling back to the station callsign for a single-op setup).
|
||||
// falling back to the station callsign for a single-op setup). The callsign and
|
||||
// operator live on the ACTIVE PROFILE (station_profiles table), NOT in the
|
||||
// settings KV — read them there.
|
||||
func (a *App) liveStatusOperator() (op, station string) {
|
||||
if a.settings == nil {
|
||||
if a.profiles == nil {
|
||||
return "", ""
|
||||
}
|
||||
o, _ := a.settings.Get(a.ctx, keyStationOperator)
|
||||
s, _ := a.settings.Get(a.ctx, keyStationCallsign)
|
||||
op = strings.ToUpper(strings.TrimSpace(o))
|
||||
station = strings.ToUpper(strings.TrimSpace(s))
|
||||
p, err := a.profiles.Active(a.ctx)
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
station = strings.ToUpper(strings.TrimSpace(p.Callsign))
|
||||
op = strings.ToUpper(strings.TrimSpace(p.Operator))
|
||||
if op == "" {
|
||||
op = station
|
||||
}
|
||||
return op, station
|
||||
}
|
||||
|
||||
// publishLiveStatus upserts this operator's current activity. Best effort.
|
||||
// ReportLiveActivity is called by the UI with the current entry-strip freq/band/
|
||||
// mode, used as a fallback for live status when the CAT isn't connected.
|
||||
func (a *App) ReportLiveActivity(freqHz int64, band, mode string) {
|
||||
a.liveActMu.Lock()
|
||||
a.liveFreqHz = freqHz
|
||||
a.liveBand = strings.ToUpper(strings.TrimSpace(band))
|
||||
a.liveMode = strings.ToUpper(strings.TrimSpace(mode))
|
||||
a.liveActMu.Unlock()
|
||||
}
|
||||
|
||||
// publishLiveStatus upserts this operator's current activity. Best effort, with
|
||||
// explicit logging so a silent no-op is diagnosable.
|
||||
func (a *App) publishLiveStatus() {
|
||||
if !a.liveStatusActive() {
|
||||
return
|
||||
if a.logDb == nil || a.dbBackend != "mysql" {
|
||||
return // not a MySQL logbook — nothing to do (silent, runs every 15s)
|
||||
}
|
||||
if !a.GetLiveStatusEnabled() {
|
||||
return // disabled (silent)
|
||||
}
|
||||
op, station := a.liveStatusOperator()
|
||||
if op == "" {
|
||||
applog.Printf("livestatus: nothing published — no operator/callsign set (Settings → Station)")
|
||||
return
|
||||
}
|
||||
var freqHz int64
|
||||
@@ -103,8 +120,21 @@ func (a *App) publishLiveStatus() {
|
||||
freqHz, band, mode = st.FreqHz, st.Band, st.Mode
|
||||
}
|
||||
}
|
||||
// Fall back to whatever the entry strip last reported (so band/mode/freq are
|
||||
// published even when the CAT isn't connected).
|
||||
a.liveActMu.Lock()
|
||||
if freqHz == 0 {
|
||||
freqHz = a.liveFreqHz
|
||||
}
|
||||
if band == "" {
|
||||
band = a.liveBand
|
||||
}
|
||||
if mode == "" {
|
||||
mode = a.liveMode
|
||||
}
|
||||
a.liveActMu.Unlock()
|
||||
if err := a.ensureLiveStatusTable(); err != nil {
|
||||
applog.Printf("livestatus: ensure table: %v", err)
|
||||
applog.Printf("livestatus: CREATE TABLE failed: %v", err)
|
||||
return
|
||||
}
|
||||
_, err := a.logDb.ExecContext(a.ctx,
|
||||
@@ -114,8 +144,10 @@ func (a *App) publishLiveStatus() {
|
||||
"band=VALUES(band), mode=VALUES(mode), updated_at=UTC_TIMESTAMP()",
|
||||
op, station, freqHz, band, mode)
|
||||
if err != nil {
|
||||
applog.Printf("livestatus: publish: %v", err)
|
||||
applog.Printf("livestatus: INSERT failed: %v", err)
|
||||
return
|
||||
}
|
||||
applog.Printf("livestatus: published op=%s station=%s %dHz %s %s", op, station, freqHz, band, mode)
|
||||
}
|
||||
|
||||
func (a *App) ensureLiveStatusTable() error {
|
||||
|
||||
Reference in New Issue
Block a user