Add queue diagnostics page#48
Merged
salvageop merged 11 commits intoJun 18, 2026
Merged
Conversation
Adds a new diagnostics page under Config menu to monitor and manage Oban job queues. Helps troubleshoot stuck or failed jobs without needing to query the database directly. Features: - System overview (pending downloads, total media, sources, db size) - Queue health status with running/available/scheduled/retryable counts - Stuck jobs detection (executing > 30 min) with reset/cancel actions - Failed jobs list with error details and bulk reset option
Use new HEEx syntax with curly braces for expressions and fix line length issues with multi-line attribute formatting. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Collaborator
|
I like this idea. I'll try to get this tomorrow |
The diagnostics page counted every un-downloaded item that wasn't explicitly prevented, ignoring source cutoff dates, shorts/livestream preferences, title regex and duration limits. This massively inflated the figure (10k+ on real systems) versus what the app actually schedules. Reuse MediaQuery.pending/0 so the count matches reality.
Split the failed-jobs card into Retryable and Discarded tabs so jobs that exhausted their retries (previously invisible) are surfaced. Retryable stays the default tab and remains the basis for queue health status. Reset now also works on discarded jobs to re-queue them. UI: drop the red exclamation-circle icon (made a healthy page look alarming) and use a plain heading consistent with the cards above.
reset_job/cancel_job called String.to_integer/1 on the :id path param, raising (500) on any non-numeric input. Parse with Integer.parse/1 and flash a clear error instead.
SQLite keeps a -wal and -shm sidecar alongside the main db file. The diagnostics page only stat'd the main file, under-reporting actual on-disk usage. Sum all three.
The queue names were hardcoded, so any change to the Oban queues config would silently omit queues from the diagnostics page. Read them from the configured Oban queues instead.
The App Info page held only two buttons (Copy Diagnostic Info, Download Logs). Move them into the Diagnostics page header and remove the now-empty App Info page, route, and sidebar entry. diagnostic_info_string/0 moves to DiagnosticsHTML; download-logs error redirect and the 500 page link now point at /diagnostics.
Resetting an executing job to available via raw update_all could start a second copy of a still-running job concurrently (duplicate yt-dlp downloads, file races, higher IP-ban risk). Genuine orphans are already recovered safely at boot by PreJobStartupTasks (runs before Oban starts, so every executing row is provably orphaned), so the on-demand reset was both redundant and dangerous. - Drop the 'Reset All Stuck Jobs' bulk action, its route, controller action and QueueDiagnostics.reset_stuck_jobs/1 - Remove the per-row Reset link from the long-running jobs table; keep Cancel, which goes through Oban.cancel_job/1 and stops a live process - Exclude 'executing' from reset_job/1 so no reset path can touch a live job - Reframe the section as 'Long-Running Jobs' with accurate copy
Collaborator
|
Hi @profesorabbott so there turned out to be a few gotchas in this PR:
|
salvageop
added a commit
that referenced
this pull request
Jun 18, 2026
* Add queue diagnostics page Adds a new diagnostics page under Config menu to monitor and manage Oban job queues. Helps troubleshoot stuck or failed jobs without needing to query the database directly. Features: - System overview (pending downloads, total media, sources, db size) - Queue health status with running/available/scheduled/retryable counts - Stuck jobs detection (executing > 30 min) with reset/cancel actions - Failed jobs list with error details and bulk reset option * Fix heex template formatting Use new HEEx syntax with curly braces for expressions and fix line length issues with multi-line attribute formatting. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Use Enum.map_join instead of Enum.map |> Enum.join Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: count pending downloads using canonical MediaQuery.pending The diagnostics page counted every un-downloaded item that wasn't explicitly prevented, ignoring source cutoff dates, shorts/livestream preferences, title regex and duration limits. This massively inflated the figure (10k+ on real systems) versus what the app actually schedules. Reuse MediaQuery.pending/0 so the count matches reality. * feat: show discarded jobs in diagnostics and align failed-jobs UI Split the failed-jobs card into Retryable and Discarded tabs so jobs that exhausted their retries (previously invisible) are surfaced. Retryable stays the default tab and remains the basis for queue health status. Reset now also works on discarded jobs to re-queue them. UI: drop the red exclamation-circle icon (made a healthy page look alarming) and use a plain heading consistent with the cards above. * fix: guard diagnostics job actions against non-integer ids reset_job/cancel_job called String.to_integer/1 on the :id path param, raising (500) on any non-numeric input. Parse with Integer.parse/1 and flash a clear error instead. * fix: include WAL/SHM files in reported database size SQLite keeps a -wal and -shm sidecar alongside the main db file. The diagnostics page only stat'd the main file, under-reporting actual on-disk usage. Sum all three. * fix: derive diagnostics queue list from Oban config The queue names were hardcoded, so any change to the Oban queues config would silently omit queues from the diagnostics page. Read them from the configured Oban queues instead. * refactor: fold App Info buttons into Diagnostics, drop App Info page The App Info page held only two buttons (Copy Diagnostic Info, Download Logs). Move them into the Diagnostics page header and remove the now-empty App Info page, route, and sidebar entry. diagnostic_info_string/0 moves to DiagnosticsHTML; download-logs error redirect and the 500 page link now point at /diagnostics. * fix: remove unsafe stuck-job reset to prevent double execution Resetting an executing job to available via raw update_all could start a second copy of a still-running job concurrently (duplicate yt-dlp downloads, file races, higher IP-ban risk). Genuine orphans are already recovered safely at boot by PreJobStartupTasks (runs before Oban starts, so every executing row is provably orphaned), so the on-demand reset was both redundant and dangerous. - Drop the 'Reset All Stuck Jobs' bulk action, its route, controller action and QueueDiagnostics.reset_stuck_jobs/1 - Remove the per-row Reset link from the long-running jobs table; keep Cancel, which goes through Oban.cancel_job/1 and stops a live process - Exclude 'executing' from reset_job/1 so no reset path can touch a live job - Reframe the section as 'Long-Running Jobs' with accurate copy --------- Co-authored-by: Daniel Da Cunha <daniel@ddc.im> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: salvageop <293462701+salvageop@users.noreply.github.com> Co-authored-by: salvageop <293462701+CommunityMaintained@users.noreply.github.com>
salvageop
added a commit
that referenced
this pull request
Jun 19, 2026
* Add queue diagnostics page (#48) * Add queue diagnostics page Adds a new diagnostics page under Config menu to monitor and manage Oban job queues. Helps troubleshoot stuck or failed jobs without needing to query the database directly. Features: - System overview (pending downloads, total media, sources, db size) - Queue health status with running/available/scheduled/retryable counts - Stuck jobs detection (executing > 30 min) with reset/cancel actions - Failed jobs list with error details and bulk reset option * Fix heex template formatting Use new HEEx syntax with curly braces for expressions and fix line length issues with multi-line attribute formatting. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Use Enum.map_join instead of Enum.map |> Enum.join Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: count pending downloads using canonical MediaQuery.pending The diagnostics page counted every un-downloaded item that wasn't explicitly prevented, ignoring source cutoff dates, shorts/livestream preferences, title regex and duration limits. This massively inflated the figure (10k+ on real systems) versus what the app actually schedules. Reuse MediaQuery.pending/0 so the count matches reality. * feat: show discarded jobs in diagnostics and align failed-jobs UI Split the failed-jobs card into Retryable and Discarded tabs so jobs that exhausted their retries (previously invisible) are surfaced. Retryable stays the default tab and remains the basis for queue health status. Reset now also works on discarded jobs to re-queue them. UI: drop the red exclamation-circle icon (made a healthy page look alarming) and use a plain heading consistent with the cards above. * fix: guard diagnostics job actions against non-integer ids reset_job/cancel_job called String.to_integer/1 on the :id path param, raising (500) on any non-numeric input. Parse with Integer.parse/1 and flash a clear error instead. * fix: include WAL/SHM files in reported database size SQLite keeps a -wal and -shm sidecar alongside the main db file. The diagnostics page only stat'd the main file, under-reporting actual on-disk usage. Sum all three. * fix: derive diagnostics queue list from Oban config The queue names were hardcoded, so any change to the Oban queues config would silently omit queues from the diagnostics page. Read them from the configured Oban queues instead. * refactor: fold App Info buttons into Diagnostics, drop App Info page The App Info page held only two buttons (Copy Diagnostic Info, Download Logs). Move them into the Diagnostics page header and remove the now-empty App Info page, route, and sidebar entry. diagnostic_info_string/0 moves to DiagnosticsHTML; download-logs error redirect and the 500 page link now point at /diagnostics. * fix: remove unsafe stuck-job reset to prevent double execution Resetting an executing job to available via raw update_all could start a second copy of a still-running job concurrently (duplicate yt-dlp downloads, file races, higher IP-ban risk). Genuine orphans are already recovered safely at boot by PreJobStartupTasks (runs before Oban starts, so every executing row is provably orphaned), so the on-demand reset was both redundant and dangerous. - Drop the 'Reset All Stuck Jobs' bulk action, its route, controller action and QueueDiagnostics.reset_stuck_jobs/1 - Remove the per-row Reset link from the long-running jobs table; keep Cancel, which goes through Oban.cancel_job/1 and stops a live process - Exclude 'executing' from reset_job/1 so no reset path can touch a live job - Reframe the section as 'Long-Running Jobs' with accurate copy --------- Co-authored-by: Daniel Da Cunha <daniel@ddc.im> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: salvageop <293462701+salvageop@users.noreply.github.com> Co-authored-by: salvageop <293462701+CommunityMaintained@users.noreply.github.com> * chore(deps): update github actions to v7 --------- Co-authored-by: profesorabbott <profesorabbott@gmail.com> Co-authored-by: Daniel Da Cunha <daniel@ddc.im> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: salvageop <293462701+salvageop@users.noreply.github.com> Co-authored-by: salvageop <293462701+CommunityMaintained@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
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.
What's new?
Adds a new diagnostics page under Config menu to monitor and manage Oban job queues. Helps troubleshoot stuck or failed jobs without needing to query the database directly.
What's changed?
Features:
What's fixed?
N/A
Any other comments?
Tested for more than a month but generated by claude code
Copied from PR Add queue diagnostics page from the original branch