feat: Opt-in track metadata cache, next_track and GET /context/tracks - #351
Merged
devgianlu merged 1 commit intoSep 14, 2026
Merged
Conversation
palchrb
force-pushed
the
claude/upstream-metadata-cache
branch
from
August 4, 2026 05:14
a163184 to
2de359c
Compare
palchrb
force-pushed
the
claude/upstream-metadata-cache
branch
from
September 1, 2026 10:02
2de359c to
178d7e0
Compare
Contributor
Author
|
Aligning with upstream as of today |
|
NOTE: I'm not a go dev, so it is tough for me to review the code. My AI liked it, but whatever. What I was able to do was test it and I got the following result: I tested this branch on real hardware. It works. Test setup
Result
Two notes that can help
I can test a large playlist next if that helps. |
Owner
|
This looks good, I did a large refactor so this needs rebasing. I would also use an exernal module for the LRU: https://github.com/hashicorp/golang-lru |
…ting Clients that render an upcoming-track preview or a browsable song list had to hit the public Web API for metadata and were getting rate limited. The daemon already talks to the internal extended-metadata endpoint for playback, so it can serve that itself: an in-memory LRU cache fed by every loaded and prefetched stream, topped up for the connect-state window around the playback position, and exposed as next_track in /status and GET /context/tracks. Everything is opt-in behind metadata.enabled: off, no cache is allocated and no request playback does not need is made. All metadata work runs detached from the player and loader lanes, coalesced onto a timer so a burst of skips costs one fetch. The LRU is hashicorp/golang-lru per review. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019FHWG4ossSBydy7jbVFWho
palchrb
force-pushed
the
claude/upstream-metadata-cache
branch
from
September 12, 2026 22:08
178d7e0 to
1405b6c
Compare
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.
Closes the second half of #346.
The API describes exactly one track — the playing one — so a client that wants to show what's coming has only the public Web API, which rate-limits. Meanwhile the daemon's own session already fetches this metadata for playback and throws it away. This keeps it: a bounded in-memory cache feeds next_track in /status and a GET /context/tracks listing for any playable context (playlist, album, artist, show, Liked Songs — built on InferSpotifyIdTypeFromContextUri from yesterday's commits).
Everything is off by default (metadata.enabled, metadata.context_sweep): disabled, no caches are constructed, every helper is a nil no-op (locked in by test), and the endpoint answers 404. Nothing blocks the control loop — enumeration runs in the background behind a ready flag, sweeps are serialised and paced at one batch of 100 per second.
Note: this and #350 both add fields to the status schema and state to AppPlayer, so they conflict trivially at a couple of insertion points. They're fully independent features — review in either order, and I'll rebase whichever is still open as soon as the other lands.