Release v0.9.9: watcher reliability hardening, config upgrade safety, and UX/logging improvements#15
Merged
loganbuilt merged 15 commits intomainfrom Mar 11, 2026
Merged
Conversation
…ghtening retry strategy, and adding candidate cooldown cache Skip yt-dlp metadata probe for music-track downloads by default (music_skip_metadata_probe=true) to reduce pre-download overhead. Keep JS runtime + cookies on first music-track attempt when configured, and avoid redundant/low-value retry branches (audio_best removed for music-track). Add SQLite-backed music candidate cooldown cache (music_candidate_failures) to temporarily suppress repeatedly unavailable candidates per recording MBID. Exclude cooled-down candidate IDs during music-track selection and clear cooldown on successful completion. Add config defaults/validation for new tuning keys: music_skip_metadata_probe music_candidate_cooldown_enabled music_candidate_cooldown_seconds music_candidate_cooldown_min_failures Add observability logs for probe skipping and candidate cooldown behavior.
…verriding existing user values.
…config_sample.json. Existing user-provided values are preserved (not overwritten). load_config(..., write_back_defaults=True) persists missing keys back to disk.
…ect sample entities like example_account.
Skew limit now accounts for: current playlist interval (watch.current_interval_min) policy max interval baseline guardrail Replaced old clamp threshold logic in watcher supervisor with this helper.
…eduler run/TG logic. Batch now waits for poll coverage: After first detection, watcher keeps a batch window open. It tracks playlists polled in that window. It triggers batch when: quiet window elapsed and all configured playlists were polled at least once, or max batch wait is hit (safety cap). It actively polls unpolled playlists during open batch window: Prevents getting stuck waiting on long per-playlist backoff before batch summary. Watcher Telegram cooldown added: If a watcher summary was just sent, next watcher summary is skipped until cooldown expires. This avoids watcher TG spam from frequent small updates. Batch attempted-count race fixed: attempted_total now uses actual batch job IDs queued by watcher run, not only completed/failed statuses at that instant. This prevents false attempted_total=0 and unintended TG skip.
…en jobs are enqueued but not yet terminal in DB.
…terminal states before sending Telegram (up to a bounded wait), instead of firing immediately after enqueue.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This release stabilizes watcher behavior and reduces false negatives/notification noise while preserving scheduler behavior. It also hardens config upgrade defaults and improves OAuth/UI/log clarity.
What’s included
Watcher reliability and batching
Reset watcher poll state on app/container startup so watched playlists poll immediately (next_poll_at=now, interval reset to min, counters reset).
Added OAuth-missing fallback path in watcher polling:
If account client is unavailable, watcher now attempts yt-dlp playlist fallback instead of hard-skipping.
Subscribe-mode detection hardened:
No longer misses unseen videos when seen items appear first.
Newly detected subscribe IDs are marked seen at detection time to prevent retrigger churn.
Batch aggregation improved (watcher-only):
Batch waits for quiet window and poll coverage across watched playlists (or max batch wait safety cap).
During open batch window, prioritizes polling unpolled playlists.
Watcher Telegram spam control:
Added watcher-only Telegram cooldown.
Watcher summary correctness:
Fixed attempted-count race by supporting watcher attempted override.
Watcher summary now waits for terminal job states (bounded wait) before dispatching Telegram, improving timing and label resolution.
Config defaults / upgrade safety
Missing config keys are auto-backfilled on load/write-back.
Backfill only adds missing keys; existing values are not overwritten.
Sample/demo entities (e.g., example_account, sample playlists) are not injected into user configs during upgrades.
Watcher skew/backoff behavior
Skew guard logic preserved but startup flow now guarantees immediate poll (prevents long idle-after-restart surprises from persisted backoff).
Logging improvements
OAuth refresh messaging updated:
Retry line normalized to: Refreshing credentials - Attempt X/Y
Success line: [Success] Credentials Refreshed account=
UI/UX
OAuth helper modal sizing improved for smaller viewports:
Modal/card constrained to viewport height with internal scrolling so action buttons remain reachable without browser zoom-out.
Non-goals / unchanged
Scheduler run summary and scheduler Telegram flow unchanged.
Core download pipeline behavior unchanged outside watcher-specific paths.
Risk / compatibility
Low-to-moderate runtime risk, scoped primarily to watcher code paths.
Config compatibility improved for upgrades; no expected breaking schema changes.
Validation performed
Static compile checks passed for modified Python modules (py_compile).
Added/updated watcher runtime hardening tests for key regressions (environment may skip certain test modules depending on local test prerequisites).