Commit graph

4 commits

Author SHA1 Message Date
BoulderBadgeDad
cea0e365c2 Fix #759: Amazon enrichment floods when its public proxy is down
After an update, installs became unusable: the Amazon enrichment worker runs by
default, the default public T2Tunes proxy (t2tunes.site) was returning
503 'Amazon Music API is not initialized', and the worker treated every album
as an individual error -- logging an ERROR per item, churning network + DB
continuously across the whole library, and marking every row 'error' (a state
the retry tiers never re-attempt, so even after the proxy recovered nothing
re-enriched). The reporter couldn't reach the UI to turn it off.

Two-part fix:

1. Source-outage circuit breaker (core/amazon_outage.py, pure + tested):
   - is_source_outage(exc) distinguishes a whole-source outage (HTTP 5xx,
     'not initialized', connection failure, non-JSON error page) from a real
     per-item miss (404, transient 400, etc.).
   - On an outage the worker now leaves the item UNTOUCHED (so it's retried once
     the proxy recovers instead of being permanently burned to 'error'), logs
     ONCE per streak, and backs off with next_poll_delay_seconds() -- escalating
     30s -> 60s -> ... capped at 30 min -- instead of grinding every 2s. It
     auto-resumes the normal cadence the moment the source answers (success OR a
     non-outage error both clear the streak).
   - AmazonClientError now carries status_code so detection doesn't rely on
     message parsing.

2. Opt-in by default (web_server.py): amazon_enrichment_paused now defaults to
   True. Because enrichment depends on an external public proxy that can be
   down, it stays paused unless the user explicitly enables it -- a proxy outage
   can no longer take down installs that never opted in. (Behaviour change:
   anyone on the old auto-on default is now paused; re-enable in Settings.)

Together: on update the worker is paused -> no flood -> UI accessible; opted-in
users are protected from future outages by the breaker.

Tests: tests/test_amazon_outage.py (12) pin the classifier across every error
surface (incl. the exact 503 'not initialized' case) and the back-off schedule
(monotonic, capped). 157 Amazon tests pass; lint clean.

Note: could not reproduce the exact 'UI fully unreachable' mechanism remotely
(WAL + 8 gthreads shouldn't hard-lock); the fix removes the flood/churn that is
the practical cause and defaults the feature off.
2026-06-01 13:10:51 -07:00
Broque Thomas
52dcdbe0f7 Harden Amazon worker schema migration
Ensure the Amazon enrichment worker verifies its required columns before querying pending work or progress, preventing upgraded installs from spamming no-such-column errors when amazon_match_status is missing.

Add regression coverage for legacy databases without Amazon enrichment columns.
2026-05-18 15:47:04 -07:00
Broque Thomas
35db1ac06d fix(lint): log S110 bare except-pass in amazon client and worker
Three ruff S110 violations replaced with logger.debug calls:
- amazon_client.py:527 duration backfill ASIN search
- amazon_client.py:679 album metadata fetch in _fetch_album_metas
- amazon_worker.py:401 artist image backfill from albums
2026-05-16 22:58:59 -07:00
Broque Thomas
4fce832ae1 Add Amazon Music enrichment worker
Background worker matching library artists/albums/tracks to Amazon ASINs
via T2Tunes search. Follows same 6-tier priority queue as Deezer/iTunes/
Spotify/Qobuz/Tidal workers. Backfills artist thumbnails from album cover
stand-ins (T2Tunes exposes no direct artist images).

- core/amazon_worker.py: new AmazonWorker class with full parity
- database/music_database.py: expand _add_amazon_columns to cover
  amazon_id/amazon_match_status/amazon_last_attempted on artists,
  albums, and tracks (was artists-only)
- web_server.py: import, init, register in enrichment panel, add to
  scan pause/resume dicts and rate monitor key map
- helper.js: WHATS_NEW 2.5.3 entry for enrichment worker
2026-05-16 17:30:48 -07:00