Harden health probe against false restarts
Probe mpv-version (always present) instead of time-pos, which live streams with caching off can report unavailable while playing fine — that produced false unhealthy verdicts. Also require 3 consecutive misses (~60s) before force-restarting a hung stream. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -232,8 +232,10 @@ func (d *Daemon) healthLoop(ctx context.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
stalls[p.Slot]++
|
stalls[p.Slot]++
|
||||||
if stalls[p.Slot] >= 2 {
|
// Require three consecutive unresponsive probes (~60s) before
|
||||||
d.log.Warn("stream stalled, forcing restart", "slot", p.Slot, "camera", p.Name)
|
// forcing a restart, so a brief IPC hiccup never bounces a stream.
|
||||||
|
if stalls[p.Slot] >= 3 {
|
||||||
|
d.log.Warn("stream hung, forcing restart", "slot", p.Slot, "camera", p.Name, "misses", stalls[p.Slot])
|
||||||
p.Stop() // Supervise relaunches
|
p.Stop() // Supervise relaunches
|
||||||
stalls[p.Slot] = 0
|
stalls[p.Slot] = 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,14 +212,17 @@ func (p *Player) Command(args ...any) (map[string]any, error) {
|
|||||||
return nil, fmt.Errorf("no reply from mpv ipc")
|
return nil, fmt.Errorf("no reply from mpv ipc")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Healthy probes mpv over IPC and reports whether it is actively playing (has
|
// Healthy probes mpv over IPC and reports whether it is responsive. It queries
|
||||||
// a finite time position advancing). A false result signals the daemon to
|
// a property that always exists (mpv-version) rather than time-pos, because a
|
||||||
// consider restarting the slot even if the process is still alive (frozen).
|
// live stream with caching disabled can legitimately report time-pos as
|
||||||
|
// unavailable while playing fine — using it here caused false "unhealthy"
|
||||||
|
// verdicts and needless restarts. A false result now means mpv's IPC didn't
|
||||||
|
// answer at all, i.e. the process is genuinely hung.
|
||||||
func (p *Player) Healthy() bool {
|
func (p *Player) Healthy() bool {
|
||||||
if !p.Running() {
|
if !p.Running() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
reply, err := p.Command("get_property", "time-pos")
|
reply, err := p.Command("get_property", "mpv-version")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user