Skip to content

feat(arrs): unified queue auto-cleanup with failure circuit breaker, Force Stop; dead-code sweep + health UI tidy#659

Merged
javi11 merged 1 commit into
javi11:mainfrom
yoshitaka420:feat/arrs-queue-cleanup-and-tidy
Jun 4, 2026
Merged

feat(arrs): unified queue auto-cleanup with failure circuit breaker, Force Stop; dead-code sweep + health UI tidy#659
javi11 merged 1 commit into
javi11:mainfrom
yoshitaka420:feat/arrs-queue-cleanup-and-tidy

Conversation

@yoshitaka420
Copy link
Copy Markdown
Contributor

Summary

Two related bodies of work, build- and test-verified together (go build + full test suite, bun run check, vite production build):

  1. Arrs queue auto-cleanup — automatic cleanup of stuck/failed imports across all six *arr types, with a per-target failure circuit breaker and an emergency Force Stop brake
  2. Dead-code sweep + health UI tidy — removal of unreferenced code repo-wide and theme-consistent colors on the health pages

1. Unified queue auto-cleanup (all six *arrs)

One cleanup pass per tick covers Radarr, Sonarr, Whisparr, Lidarr, Readarr and Sportarr (internal/arrs/worker/stuck_cleanup.go), replacing the per-type scaffold and the separate Import Failure Cleanup toggle:

  • Ghost detection: queue items whose import already landed (confirmed via import history) or whose source path is gone are removed grace-free; a confirmed healthy import also resets the failure breaker for that target
  • Message rules: configurable rule table (status-message substring → action) with actions remove / blocklist / blocklist_search, editable in the Arrs settings UI; rule actions are validated on config load and API save
  • Grace period: items are only acted on after being continuously observed stuck past arrs.queue_cleanup_grace_period_minutes, so transient errors the *arr resolves on its own are left alone
  • Safety: only queue items owned by AltMount's download client are ever touched (case-insensitive match, including renamed clients — fixes interop with other download clients' paths)

Per-target failure circuit breaker

arrs.queue_cleanup_max_failures (0 = off) counts AltMount-initiated actions per target (movie / episode / album / book) in a shared in-memory tracker (internal/arrs/failures) so a dead release cannot drive an endless grab → fail → re-grab loop. Three producers bump the same keys:

  • queue cleanup actions
  • health-repair re-searches (scanner) — at the threshold the target is unmonitored instead of re-searched
  • import failures (importer postprocessor → worker.HandleImportFailure) — catches the fast-fail loop where the *arr blocklists one GUID and instantly re-grabs the same release from another indexer; at the threshold the target is unmonitored first, then the queue record is removed with blocklist + skipRedownload

Counters reset when the target later imports healthy. In-memory only; clears on restart.

Force Stop brake

Emergency pause (API: GET/POST/DELETE /api/arrs/pause; UI control in the Queue page cleanup dropdown). While engaged, no *arr requests are issued: the cleanup tick, health-repair re-trigger, importer failure breaker and the indexer history sync all gate on it.

Related fixes

  • health: never delete library files when ARR repair path-matching misses (fail-safe instead of fail-destructive)
  • importer: post-import health checks are scheduled per written file — for multi-file imports (season packs) the old directory-path lookup failed silently and no checks were ever scheduled
  • Sportarr: included in the config API response, its indexer is captured per download for indexer-health attribution, duplicate sample rule dropped
  • docs + config.sample.yaml updated for the new options

2. Dead-code sweep + health UI tidy

Dead code removal (every removal verified by build + tests):

  • Frontend: RCloneConfigSection, ManualScanSection, ActiveStreamsCard, RecentCompletions, HealthChart, QueueChart, KeyValueEditor, plus unused exports in ErrorAlert, LoadingSpinner, BytesDisplay, useConfig, webdavClient, api client/types
  • Backend: internal/library (entire package), api/webdav auth_updaters, unused metadata/importer/utils/slogutil/encryption helpers, fuse server and rclonecli mount leftovers, unused API response helpers and routes
  • internal/database/testing.gotesting_test.go (test-only helper no longer ships in the production build)

Health UI tidy — replace hardcoded tailwind palette colors (teal/emerald/amber/rose + rgba glows) with daisyUI theme tokens so the health pages follow the active theme:

  • Indexer health: success/warning/error tokens for the three performance tiers, muted failure bar on excellent indexers, sort preference persisted in localStorage, best/worst chips and the comparison bar chart removed (low signal next to the per-indexer cards)
  • Provider health: charts source palette + tooltip/cursor from theme vars (fixes stale daisyUI v4 hsl() tooltip), provider table badges and quota vials themed via base/success/warning/error tokens

Test plan

  • go build ./... + full Go test suite green (new tests: failures tracker, worker breaker, import-failure flow with httptest fake Sonarr, registrar client matching, config validation)
  • bun run check + vite production build green
  • Cleanup + breaker verified end-to-end against a fake Sonarr (blocklist_search → escalate to blocklist+unmonitor at threshold; Force Stop halts polling)

…e sweep + health UI tidy

Combined change set: the arrs queue auto-cleanup feature plus a repo-wide
dead-code sweep and theme-consistency pass on the health UI. Tree is
build- and test-verified as a whole (go build/tests, bun check, vite build).

See PR description for details.
@javi11 javi11 merged commit cec37d8 into javi11:main Jun 4, 2026
2 checks passed
@yoshitaka420 yoshitaka420 deleted the feat/arrs-queue-cleanup-and-tidy branch June 4, 2026 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants