feat(worker): share the MusicBrainz cache from scans/discovery
The worker's MB browser (discography + artist search, used by monitor sweeps, library scans, and Last.fm discovery) re-fetched every time. Route it through the same ApiCache table + logical keys the web app uses, so a discography one process fetched warms the other, and repeat lookups stop hitting MB. - apicache.py cached_api(): read-through, serve-stale-on-outage, never caches null, best-effort (a cache-DB error degrades to a live fetch, never breaks scan/sweep/discovery). Its own DEDICATED autocommit connection so it can't commit the worker's in-flight transaction, and autocommit avoids freezing Postgres now() (which would break TTL math). - CachingMbBrowser decorates MusicBrainzBrowser, serializing to the SAME camelCase JSON shape the web writes (round-trip tested). registry.build_browser wraps it when a DSN is present; the Last.fm source's browser rides it too. - Hourly prune drops ApiCache rows > 90d so the table stays bounded. - worker 213 tests / 7-skip. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,7 @@ def conn():
|
||||
cur.execute('DELETE FROM "DiscoverySuggestion"')
|
||||
cur.execute('DELETE FROM "DiscoverySeedContribution"')
|
||||
cur.execute('DELETE FROM "ScanWorkItem"')
|
||||
cur.execute('DELETE FROM "ApiCache"')
|
||||
cur.execute('DELETE FROM "Config"')
|
||||
connection.commit()
|
||||
yield connection
|
||||
@@ -47,6 +48,7 @@ def conn():
|
||||
cur.execute('DELETE FROM "DiscoverySuggestion"')
|
||||
cur.execute('DELETE FROM "DiscoverySeedContribution"')
|
||||
cur.execute('DELETE FROM "ScanWorkItem"')
|
||||
cur.execute('DELETE FROM "ApiCache"')
|
||||
cur.execute('DELETE FROM "Config"')
|
||||
connection.commit()
|
||||
connection.close()
|
||||
|
||||
Reference in New Issue
Block a user