Explore: warm the release cache for owned albums that are not known-complete #85
Open
opened 2026-08-18 20:05:17 +00:00 by yonlu
·
0 comments
No Branch/Tag Specified
main
fix/146-stub-etxtbsy
fix/175-wizard-follows-the-library
fix/231-setter-rollback
fix/197-duplicate-column-label
docs/225-fixtures-wav-tags
docs/220-skill-check-scope
test/217-fixture-names-in-queue-selection
fix/216-riff-parse-allocation
fix/170-queue-header-action-names
fix/210-nav-sheet-scroll-affordance
docs/50-readme-landing-page
feat/65-art-prefetch-ahead
feat/71-more-as-a-bottom-sheet
feat/54-native-touch-feel
feat/67-entity-links-into-menus
test/196-visual-tier-gates
fix/138-ui-test-storage-leak
fix/104-wav-tags-read
fix/207-sheet-scroll-affordance
fix/204-ui-visual-update-filter
pi-agent-backlog-automation
63-touch-model-phase-2
63-android-touch-model
186-touch-targets-settings
186-touch-targets-page-header
187-seek-bar-hit-area
189-190-explore-correctness
135-android-underrun-instrumentation
51-android-small-screens
fix/171-phone-queue-scrim
fix/137-touch-only-affordances
fix/154-nested-css-check
feat/58-mini-player-progress-line
fix/66-album-page-scrolls-as-one
60-context-menu-action-sheet
64-android-system-volume
59-slim-the-mini-player
55-queue-as-a-screen
feat/57-drop-the-android-top-bar
feat/62-jobs-as-a-notification
fix/53-seek-bar-never-moves
fix/159-android-task-app-id
fix/52-android-activity-recreation-restarts-the-process
fix/150-expand-button-under-the-art
feat/42-inline-volume-and-centred-transport
fix/156-queue-selection-fixture-order
fix/151-fuse-the-scroll-guard-and-the-write
fix/43-queue-panel-selection
fix/143-top-bar-fits-its-window
feat/27-jobs-into-settings
feat/25-configurable-sidebar-tabs
feat/6-global-back-forward
fix/72-active-view-broadcast
fix/69-page-header-action-overflow
fix/quick-wins-batch
fix/118-in-library-clear
fix/61-mini-player-plain-text
fix/68-hover-affordances-pointer
fix/119-dev-headless-port
fix/130-issue-claim-user
fix/131-codegen-check-scope
feat/28-autotag-match-on-album
feat/17-demote-version-selector
feat/38-ownership-visibility
ci/115-manual-release
feat/34-icon-language
feat/7-full-tracklist-toggle
fix/16-tagwriter-totals
fix/unclaim-ca-certs
fix/unclaim-shell
ci/unclaim-on-close
docs/closing-keyword
docs/retire-stale-planning-docs
docs/issue-driven-workflow
integration/small-fixes
fix/small-issue-batch
fix/queue-toggle-state
fix/drag-count-badge
fix/album-card-year
fix/album-tracklist-heading
fix/seek-bar-clock-width
fix/explore-art-scanner-requests
chore/workflow-guardrails
v0.7.0
v0.6.0
v0.5.0
v0.4.0
v0.3.1
v0.3.0
v0.2.3
v0.2.2
v0.2.1
v0.2.0
v0.1.0
v0.0.1
v0.0.0
Labels
Clear labels
Area/Design
Area/Downloads
Area/Explore
Area/Library-UI
Area/Metadata
Area/Packaging
Area/Player
Area/Queue
Area/Settings
Area/Shell-Nav
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Platform/Android
Platform/Desktop
Breaking change that won't be backward compatible
Something is not working
Documentation changes
Improve existing functionality
New functionality
This is security issue
Issue or pull request related to testing
Priority
Critical
1
The priority is critical
Priority
High
2
The priority is high
Priority
Medium
3
The priority is medium
Priority
Low
4
The priority is low
Reviewed
Confirmed
1
Issue has been confirmed
Reviewed
Duplicate
2
This issue or pull request already exists
Reviewed
Invalid
3
Invalid issue
Reviewed
Won't Fix
3
This issue won't be fixed
Status
Blocked
1
Something is blocking this issue or pull request
Status
Need More Info
2
Feedback is required to reproduce issue or to continue work
Status
Abandoned
3
Somebody has started to work on this but abandoned work
Status
In Progress
Somebody is actively working on this right now
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: yonlu/yellowjacket#85
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Opening an album detail page for an album you already own hits MusicBrainz, every time it is not in the response cache — which for most of a library is every time, because nothing warms that cache except a capped prefetch on the artist page.
Converted from
.planning/plans/pending/010-owned-album-catalog-offline.md, which is deleted in favour of this issue.What already shipped, and what it leaves
The common case is solved.
GetAlbumCompletenessreads the "5/12" denominator off the files' own tags, and an album that is MBID-matched and complete now opens with no catalog call at all — identity from the MBID, tracklist from the tags, which were the two things the browse was being spent on.So the set left to serve is not "albums you own a track of". It is:
On a well-tagged library that is a small minority, which changes the economics considerably. Re-measure before building — the answer may now be "the prefetch is enough".
Why the discography backfill does not already cover it
BackfillLibraryDiscographies/EnsureArtistDiscographywrite flatexplore_indexrows. There is no release group → tracklist relation anywhere in the index and no release-level rows at all;caa_release_mbidandrelease_namename the release used for cover art, not a tracklist. "We have full discographies for library artists" means we know which albums the artist made, offline. It has never meant we know what is on any of them.The only store of release-level catalog data is
http_cacheundermb:browse:releases:<rg>(90-day TTL), populated only by a liveBrowseReleaseswithIncludes: ["recordings", "media"]— the most expensive call the app makes — and warmed by exactly one thing,PrefetchReleases, capped at 8 and called only when an artist page renders.What to build
A post-scan backfill that warms the release cache for release groups that are owned but not known-complete — bounded, resumable, shaped like
BackfillLibraryDiscographies, which is the proven pattern here.audio_files, like every other ownership question in this codebase.releasesSF, so it never double-fetches a release group an interactive open is already handling.discogBackfillMaxPerRunhas a value to copy). The resume marker is the response cache itself —BrowseReleasesCachedalready answers "is this one done", so unlike the discography path this needs no new flag column.jobsso it has progress, pause and cancel like every other long-running operation, and mark its context withWithBackgroundPriority.The rate-limiter half of the original plan is already built:
RateLimiter.WithBackgroundLane+WithBackgroundPriority(ctx)make a marked caller yield to interactive work, andjobs.KindCatalogEnrich+startBackfillJobgive the existing backfills progress and cancel.PrefetchReleases' cap of 8 is still unrevisited and should be looked at in the same change.The alternative that was considered and rejected
Projecting release-group tracklists in the dump build and shipping them in the artifact. The data is there and it is derivable from bytes the index build already streams. It is rejected because the artifact is built centrally and is byte-identical for every user, so "albums the user owns a track of" cannot be a filter on it.
The argument that actually kills it: the popularity floor is not one number over artists but a per-artist track budget (50 tracks tier A, 25 tier B, 12 tier C). A projected tracklist would be whichever of an album's tracks survived that budget, with nothing marking the rest absent — so the album page would count owned against a truncated denominator and render "Play 7 of 9" for a twelve-track album. That is a confident lie, where the states this approach produces (complete / incomplete / unknown) are at worst silent.
Worth revisiting only if the artifact ever gains per-user tailoring.
Done when