[1.20.3] - 2026-06-07
Fixed
-
Ghost heartbeat after restart no longer blocks EPG refresh: When Dispatcharr restarts, the dying monitoring thread writes a final heartbeat just before exit. Previously this "ghost" heartbeat caused
_handle_refresh,_handle_start_monitoring,_try_claim_monitor, and_ensure_monitoring_threadto treat the instance as healthy and skip restarting — leaving EPG data stale for up to 28 hours. All four now require both a recent heartbeat and a recentlast_poll_timeto consider monitoring healthy. A fresh heartbeat alone no longer suppresses a restart when the last poll is stale. -
Missing EPG ProgramData rows are now created:
_refresh_epg_timespreviously used.update()only, which silently did nothing if a channel'sProgramDatarow was absent. It now falls back toupdate_or_create, ensuring EPG entries are created for channels that lost their program rows (e.g., after a database migration or first-time setup).
Added
last_poll_age_secondsin diagnostics: The diagnostics action now reports the age of the last successful poll in seconds.- Stale-poll warning in diagnostics: When
monitoring_active=Truebutlast_poll_timeis stale, diagnostics surfaces awarning:monitoring active but last poll is staleissue. - EPG window counts in diagnostics:
epg_window_countsreports the number of current and next-12h programs in the YouTubearr EPG source, and warns when the source has no current or future programs while monitoring appears active.
Internal
- Added
_parse_iso_datetime(value),_age_seconds(value),_is_last_poll_recent(settings), and_get_youtubearr_epg_window_counts(settings)helpers. - New unit tests covering: stale-poll detection helpers, fresh-heartbeat-alone not healthy,
_handle_refreshand_handle_start_monitoringbehavior with ghost heartbeat,_ensure_monitoring_threadheartbeat+poll combined guard, and diagnostics new fields.