Skip to content

feat: implement granular search by type in subsonic provider - #903

Open
soyelmismo wants to merge 11 commits into
supersonic-app:mainfrom
soyelmismo:feat/granular-search-types
Open

feat: implement granular search by type in subsonic provider#903
soyelmismo wants to merge 11 commits into
supersonic-app:mainfrom
soyelmismo:feat/granular-search-types

Conversation

@soyelmismo

Copy link
Copy Markdown

Problem:
Generic Search3 requests include all media types by default. This causes unnecessary processing and network load when the user is searching within a specific category (e.g., only Albums).

Changes:

  • Expanded /backend/mediaprovider/subsonic/searchiterbase.go to support independent Count parameters.
  • Updated /backend/mediaprovider/subsonic/albumiterator.go/SearchArtists and SearchTracks to request exclusively their own type by setting other counts to 0.
  • This optimizes search performance and reduces response size for category-specific views.

BEFORE (Generic Search)
When the user searched in the "Albums" section, the client asked for everything and the server wasted resources on Tidal looking for artists and tracks that were not going to be used.

// Request asking for 20 of each thing obligatorily
GET /search3?query=odyssey&albumOffset=0&artistOffset=0&songOffset=0

// Heavy load of 3 types of data
[SUBS] Search results ready for query "odyssey": tracks=20 artists=3 albums=20
[SUBS] OUT GET /search3 (1.16s)

AFTER (Granular Search - Category: Albums)
With the fix, the client specifies that it only wants albums (artistCount=0, songCount=0). The server responds much faster and with clean data.

// Granular request (Only Albums)
GET /search3?query=ody&albumCount=50&artistCount=0&songCount=0

// It results on efficient load depending on where the user is standing at.
[SUBS] Search results ready for query "ody": tracks=0 artists=0 albums=25
[SUBS] OUT GET /search3 (0.87s) // ~25% faster and without junk traffic
  • The response payload is ~60% smaller.
  • Backend only executes 1 query instead of 3.
  • Clean server logs are clean of irrelevant metadata.

@soyelmismo

Copy link
Copy Markdown
Author

uh, looks like I accidentally sneaked in a commit for another fix I had lying around: I was disabling an aggressive prefetching in the search iterators.

Supersonic was firing extra requests (getArtist/getAlbum) for every single search result just to hydrate discographies that weren't even needed yet. So yeah, now search is snappier 😅 and atomic—it just takes what the server sends and stops there.

@dweymouth

Copy link
Copy Markdown
Collaborator

This removes functionality. It removes the ability to search for an artist name on the albums page and see their discography in the results. And to search a song by name and see its containing album in the results. If you can find a way to improve the performance for your use case while preserving this functionality (which works well for servers with locally-hosted and indexed libraries, even very large ones), then I will consider merging. But I'm not keen on removing functionality to better support non-locally-hosted libraries.

@soyelmismo

Copy link
Copy Markdown
Author

I see...

How about a Smart Hybrid Search?

  1. Request only the primary type (e.g., Albums with count=50).
  2. If results are low (e.g., < 10 albums), trigger a small side-request for Artists (count=3) GetArtist

This keeps the "discography via search" magic alive without nuking the server with 3x heavy requests on every single keystroke. Looks balanced.

Thoughts?

@dweymouth

Copy link
Copy Markdown
Collaborator

That sounds reasonable to me! Make sure to do the side request for Songs too to allow for the "find what album contains this song" search

soyelmismo added 4 commits April 9, 2026 14:52
… results are sparse and ignore .fuse files
… artist/album

Split combined error check into distinct handling:
 1. Log explicit API fetch failure errors
 2. Add separate logging when requested entry is not found

This improves debug visibility by clearly distinguishing different failure modes during album search iteration.
Fixes invalid parameter passed when constructing the random album iterator.
Was incorrectly using s.prefetchCoverCB instead of the properly prepared
cb variable intended for this iterator instance.
@soyelmismo

soyelmismo commented Apr 9, 2026

Copy link
Copy Markdown
Author

perfect. my searches now don't get hang waiting 1000 artists, while keeping the artist albums

also, I noticed the client seems to wait for all covers to load before fully rendering the object list, which creates a significant bottleneck on high-latency CDNs. I found that the prefetchCoverCB inside the iterators is firing dozens of concurrent requests that might be stalling the main UI thread's network queue.

I can fix this by making the cover prefetching truly lazy/asynchronous or removing the blocking wait. If you'd like I can include that fix in this PR as well to keep things snappy! :p

@dweymouth

Copy link
Copy Markdown
Collaborator

I think the cover prefetch can probably go away entirely. It was mostly premature optimization :) especially when cached locally, there is no / barely a perceptible delay in reading a cover from disk and displaying it async. probably worth removing the prefetch entirely for simplicity and to improve code maintainability

@soyelmismo

Copy link
Copy Markdown
Author

oh wow now it is a bullet

… iterators

Removed all unused album cover prefetch callback logic:
- Remove callback registration from app startup
- Strip prefetchCB field from all media iterator types
- Clean up iterator constructor signatures
- Drop async cover prefetching during media iteration

This removes dead code that was no longer needed, simplifies iterator
implementations and removes unnecessary background image fetch operations.
@soyelmismo

Copy link
Copy Markdown
Author

i dont see any major optimization by now, everything is loading instantly now. can be merged.

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