From 1caf4a184cf7092b60171f2fcf74acbeefd47549 Mon Sep 17 00:00:00 2001 From: Danielle McLean Date: Thu, 9 May 2024 12:12:54 +1000 Subject: [PATCH] Cache 'no artwork', rather than repeatedly populating the cache with None --- src/mpd_now_playable/mpd/artwork_cache.py | 31 +++++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/mpd_now_playable/mpd/artwork_cache.py b/src/mpd_now_playable/mpd/artwork_cache.py index b4fad7c..13819b1 100644 --- a/src/mpd_now_playable/mpd/artwork_cache.py +++ b/src/mpd_now_playable/mpd/artwork_cache.py @@ -1,3 +1,5 @@ +from dataclasses import dataclass + from aiocache import Cache from ..async_tools import run_background_task @@ -6,6 +8,25 @@ from .types import CurrentSongResponse, MpdStateHandler CACHE_TTL = 60 * 10 # ten minutes +@dataclass(frozen=True) +class HasArt: + data: bytes + + +@dataclass(frozen=True) +class HasNoArt: + data = None + + +ArtCacheEntry = HasArt | HasNoArt + + +def make_cache_entry(art: bytes | None) -> ArtCacheEntry: + if art is None: + return HasNoArt() + return HasArt(art) + + def calc_album_key(song: CurrentSongResponse) -> str: artist = song.get("albumartist", song.get("artist", "Unknown Artist")) album = song.get("album", "Unknown Album") @@ -18,8 +39,8 @@ def calc_track_key(song: CurrentSongResponse) -> str: class MpdArtworkCache: mpd: MpdStateHandler - album_cache: "Cache[bytes | None]" - track_cache: "Cache[bytes | None]" + album_cache: "Cache[ArtCacheEntry]" + track_cache: "Cache[ArtCacheEntry]" def __init__(self, mpd: MpdStateHandler): self.mpd = mpd @@ -29,7 +50,7 @@ class MpdArtworkCache: async def get_cached_artwork(self, song: CurrentSongResponse) -> bytes | None: art = await self.track_cache.get(calc_track_key(song)) if art: - return art + return art.data # If we don't have track artwork cached, go find some. run_background_task(self.cache_artwork(song)) @@ -37,12 +58,12 @@ class MpdArtworkCache: # Even if we don't have cached track art, we can try looking for cached album art. art = await self.album_cache.get(calc_album_key(song)) if art: - return art + return art.data return None async def cache_artwork(self, song: CurrentSongResponse) -> None: - art = await self.mpd.readpicture(song["file"]) + art = make_cache_entry(await self.mpd.readpicture(song["file"])) try: await self.album_cache.add(calc_album_key(song), art, ttl=CACHE_TTL) except ValueError: