0.1.52 Gateway

This commit is contained in:
ponzischeme89
2026-08-17 19:09:17 +12:00
parent d5a8d3ad88
commit 1da91e40a1
46 changed files with 1626 additions and 106 deletions
+27 -10
View File
@@ -112,27 +112,34 @@ func librarySyncTitle(changed int) string {
//
// Only *transitions* are announced. A server that is down stays down, and repeating it
// every minute would bury everything else.
func (s *Server) WatchEmbyReachability(ctx context.Context, interval time.Duration) {
if interval <= 0 {
return
}
ticker := time.NewTicker(interval)
defer ticker.Stop()
// The cadence is read on every tick rather than fixed at start-up, because it is an
// operator setting the console can change: a loop that captured it would leave the one
// probe an operator is most likely to want to slow down or switch off needing a restart
// of the gateway to do either. A probe that is off still ticks, slowly, so that turning
// it back on does not need one either.
func (s *Server) WatchEmbyReachability(ctx context.Context) {
// Start out assuming reachable: a gateway booting while Emby is down should not
// open with a banner about a state nobody has seen change.
reachable := true
failures := 0
interval := s.embyHealthInterval()
// The same probe feeds the live state on /v1/status, so one request to Emby answers
// both "did this just change" and "is it working right now". Declared before the
// first tick so a client asking during the opening minute learns the retry interval.
s.embyHealth.begin(interval, time.Now().UTC())
s.embyHealth.retune(interval, time.Now().UTC())
timer := time.NewTimer(embyProbeDelay(interval))
defer timer.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if s.quietTimeActive() {
case <-timer.C:
if next := s.embyHealthInterval(); next != interval {
interval = next
s.embyHealth.retune(interval, time.Now().UTC())
}
timer.Reset(embyProbeDelay(interval))
if interval <= 0 || s.quietTimeActive() {
continue
}
probeCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
@@ -160,6 +167,16 @@ func (s *Server) WatchEmbyReachability(ctx context.Context, interval time.Durati
}
}
// embyProbeDelay is how long to wait before looking again. With the probe switched off it
// is the interval at which the loop asks whether it has been switched back on, which is a
// minute because nothing is watching and nothing is being asked of Emby.
func embyProbeDelay(interval time.Duration) time.Duration {
if interval <= 0 {
return time.Minute
}
return interval
}
// reachabilityAlert is timestamped per transition, so the "back online" banner never
// collides with the "not responding" one it replaces.
func (s *Server) reachabilityAlert(up bool) clientAlert {