perf(reco): batch id->entity hydration
radio/similar resolved ids one get_by_id at a time (N round-trips). Add TrackRepository.get_many and use it (plus ArtistRepository.get_many) to hydrate in a single query, preserving requested order. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -82,8 +82,8 @@ class RecommendationService:
|
||||
if self._recommender.is_available():
|
||||
ids = await self._recommender.similar_artist_ids(artist_id, limit=limit)
|
||||
if ids is not None:
|
||||
found = [a for i in ids if (a := await self._artists.get_by_id(i))]
|
||||
return REASON_ML, found
|
||||
by_id = {a.id: a for a in await self._artists.get_many(ids)}
|
||||
return REASON_ML, [by_id[i] for i in ids if i in by_id]
|
||||
|
||||
found = await self._artists.list_similar(artist_id=artist_id, limit=limit)
|
||||
return REASON_SIMILAR, found
|
||||
@@ -183,5 +183,7 @@ class RecommendationService:
|
||||
return None, REASON_DISCOVER
|
||||
|
||||
async def _hydrate_tracks(self, ids: list[uuid.UUID]) -> list[Track]:
|
||||
"""Resolve ids → tracks preserving order, skipping any that vanished."""
|
||||
return [t for i in ids if (t := await self._tracks.get_by_id(i))]
|
||||
"""Resolve ids → tracks preserving order, skipping any that vanished.
|
||||
One batched query rather than N per-id round-trips."""
|
||||
by_id = {t.id: t for t in await self._tracks.get_many(ids)}
|
||||
return [by_id[i] for i in ids if i in by_id]
|
||||
|
||||
Reference in New Issue
Block a user