[gnome-music/wip/mschraal/insanely-slow-startup-fix] grltrackerwrapper: Use GriloArtQueue for art retrieval




commit d7d66d1b72c892c64939126128fd4188b00436b6
Author: Marinus Schraal <mschraal gnome org>
Date:   Tue Feb 15 10:28:35 2022 +0100

    grltrackerwrapper: Use GriloArtQueue for art retrieval
    
    Serializes art lookups through Grilo as this is too taxing when doing in
    parallel.
    
    Fixes: #472

 gnomemusic/albumart.py                        |  6 +++++-
 gnomemusic/artistart.py                       |  7 ++++++-
 gnomemusic/coregrilo.py                       | 18 ++++++++++++------
 gnomemusic/griloartqueue.py                   |  5 +++--
 gnomemusic/grilowrappers/grltrackerwrapper.py | 27 ++++++++++++++++++++-------
 gnomemusic/songart.py                         |  4 +++-
 6 files changed, 49 insertions(+), 18 deletions(-)
---
diff --git a/gnomemusic/albumart.py b/gnomemusic/albumart.py
index f61db97e9..6e3348dfa 100644
--- a/gnomemusic/albumart.py
+++ b/gnomemusic/albumart.py
@@ -29,6 +29,8 @@ from gi.repository import GObject, MediaArt
 from gnomemusic.asyncqueue import AsyncQueue
 from gnomemusic.embeddedart import EmbeddedArt
 from gnomemusic.fileexistsasync import FileExistsAsync
+from gnomemusic.griloartqueue import GriloArtQueue
+from gnomemusic.utils import CoreObjectType
 
 
 class AlbumArt(GObject.GObject):
@@ -50,13 +52,15 @@ class AlbumArt(GObject.GObject):
         self._album = self._corealbum.props.title
         self._artist = self._corealbum.props.artist
 
+        self._grilo_art_queue = GriloArtQueue(application)
+
         self._in_cache()
 
     def _on_embedded_art_found(self, embeddedart, found):
         if found:
             self._in_cache()
         else:
-            self._coregrilo.get_album_art(self._corealbum)
+            self._grilo_art_queue.queue(self._corealbum, CoreObjectType.ALBUM)
 
     def _in_cache(self):
         success, thumb_file = MediaArt.get_file(
diff --git a/gnomemusic/artistart.py b/gnomemusic/artistart.py
index 6605748c8..c93606583 100644
--- a/gnomemusic/artistart.py
+++ b/gnomemusic/artistart.py
@@ -28,6 +28,8 @@ from gi.repository import GObject, MediaArt
 
 from gnomemusic.asyncqueue import AsyncQueue
 from gnomemusic.fileexistsasync import FileExistsAsync
+from gnomemusic.griloartqueue import GriloArtQueue
+from gnomemusic.utils import CoreObjectType
 
 
 class ArtistArt(GObject.GObject):
@@ -48,6 +50,8 @@ class ArtistArt(GObject.GObject):
         self._coregrilo = application.props.coregrilo
         self._artist = self._coreartist.props.artist
 
+        self._grilo_art_queue = GriloArtQueue(application)
+
         self._in_cache()
 
     def _in_cache(self):
@@ -60,7 +64,8 @@ class ArtistArt(GObject.GObject):
             if result:
                 self._coreartist.props.thumbnail = thumb_file.get_uri()
             else:
-                self._coregrilo.get_artist_art(self._coreartist)
+                self._grilo_art_queue.queue(
+                    self._coreartist, CoreObjectType.ARTIST)
 
         file_exists_async = FileExistsAsync()
         file_exists_async.connect(
diff --git a/gnomemusic/coregrilo.py b/gnomemusic/coregrilo.py
index 002d5b921..b94f4d1ff 100644
--- a/gnomemusic/coregrilo.py
+++ b/gnomemusic/coregrilo.py
@@ -242,29 +242,35 @@ class CoreGrilo(GObject.GObject):
         for wrapper in self._search_wrappers.values():
             wrapper.search(text)
 
-    def get_song_art(self, coresong):
+    def get_song_art(self, coresong, storeart=None):
         """Retrieve song art for the given CoreSong
 
         :param CoreSong coresong: CoreSong to retrieve art for
+        :param StoreArt storeart: StoreArt instance or None
         """
         if "grl-tracker3-source" in self._wrappers:
-            self._wrappers["grl-tracker3-source"].get_song_art(coresong)
+            self._wrappers["grl-tracker3-source"].get_song_art(
+                coresong, storeart)
 
-    def get_album_art(self, corealbum):
+    def get_album_art(self, corealbum, storeart=None):
         """Retrieve album art for the given CoreAlbum
 
         :param CoreAlbum corealbum: CoreAlbum to retrieve art for
+        :param StoreArt storeart: StoreArt instance or None
         """
         if "grl-tracker3-source" in self._wrappers:
-            self._wrappers["grl-tracker3-source"].get_album_art(corealbum)
+            self._wrappers["grl-tracker3-source"].get_album_art(
+                corealbum, storeart)
 
-    def get_artist_art(self, coreartist):
+    def get_artist_art(self, coreartist, storeart=None):
         """Retrieve artist art for the given CoreArtist
 
         :param CoreArtist coreartist: CoreArtist to retrieve art for
+        :param StoreArt storeart: StoreArt instance or None
         """
         if "grl-tracker3-source" in self._wrappers:
-            self._wrappers["grl-tracker3-source"].get_artist_art(coreartist)
+            self._wrappers["grl-tracker3-source"].get_artist_art(
+                coreartist, storeart)
 
     def stage_playlist_deletion(self, playlist):
         """Prepares playlist deletion.
diff --git a/gnomemusic/griloartqueue.py b/gnomemusic/griloartqueue.py
index b406217c1..71c4d48d7 100644
--- a/gnomemusic/griloartqueue.py
+++ b/gnomemusic/griloartqueue.py
@@ -23,7 +23,7 @@
 # delete this exception statement from your version.
 
 from __future__ import annotations
-from typing import Callable, Dict, List, Optional, Union
+from typing import Dict, List, Union
 import typing
 
 from gi.repository import GLib, GObject
@@ -100,4 +100,5 @@ class GriloArtQueue(GObject.GObject):
 
     def _on_async_finished(
             self, storeart: StoreArt, coreobject: CoreObject) -> None:
-        self._active_queue.remove(coreobject)
+        if coreobject in self._active_queue:
+            self._active_queue.remove(coreobject)
diff --git a/gnomemusic/grilowrappers/grltrackerwrapper.py b/gnomemusic/grilowrappers/grltrackerwrapper.py
index fefcb00b9..b916593e2 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -37,7 +37,6 @@ from gnomemusic.coredisc import CoreDisc
 from gnomemusic.coresong import CoreSong
 from gnomemusic.grilowrappers.grltrackerplaylists import (
     GrlTrackerPlaylists, Playlist)
-from gnomemusic.storeart import StoreArt
 from gnomemusic.trackerwrapper import TrackerWrapper
 from gnomemusic.utils import CoreObjectType
 if typing.TYPE_CHECKING:
@@ -45,6 +44,7 @@ if typing.TYPE_CHECKING:
     from gnomemusic.coremodel import CoreModel
     from gnomemusic.musiclogger import MusicLogger
     from gnomemusic.notificationmanager import NotificationManager
+    from gnomemusic.storeart import StoreArt
 
 
 class GrlTrackerWrapper(GObject.GObject):
@@ -1181,7 +1181,7 @@ class GrlTrackerWrapper(GObject.GObject):
 
         return query
 
-    def get_song_art(self, coresong: CoreSong) -> None:
+    def get_song_art(self, coresong: CoreSong, storeart: StoreArt) -> None:
         """Retrieve song art for the given CoreSong
 
         Since MediaArt does not really support per-song art this
@@ -1189,6 +1189,7 @@ class GrlTrackerWrapper(GObject.GObject):
         art and store it.
 
         :param CoreSong coresong: CoreSong to get art for
+        :param StoreArt storeart: StoreArt instance to use
         """
         media: Grl.Media = coresong.props.media
 
@@ -1205,13 +1206,14 @@ class GrlTrackerWrapper(GObject.GObject):
                 error: Optional[GLib.Error]) -> None:
             if error:
                 self._log.warning("Error: {}".format(error))
+                self.emit("finished")
                 return
 
             if queried_media is None:
                 return
 
             self._async_queue.queue(
-                StoreArt(), coresong, queried_media.get_thumbnail(),
+                storeart, coresong, queried_media.get_thumbnail(),
                 CoreObjectType.SONG)
 
         song_id: str = media.get_id()
@@ -1221,10 +1223,11 @@ class GrlTrackerWrapper(GObject.GObject):
             query, self._METADATA_THUMBNAIL_KEYS, self._full_options_lprio,
             art_retrieved_cb)
 
-    def get_album_art(self, corealbum: CoreAlbum) -> None:
+    def get_album_art(self, corealbum: CoreAlbum, storeart: StoreArt) -> None:
         """Retrieve album art for the given CoreAlbum
 
         :param CoreAlbum corealbum: CoreAlbum to get art for
+        :param StoreArt storeart: StoreArt instance to use
         """
         media: Grl.Media = corealbum.props.media
 
@@ -1234,13 +1237,14 @@ class GrlTrackerWrapper(GObject.GObject):
                 error: Optional[GLib.Error]) -> None:
             if error:
                 self._log.warning("Error: {}".format(error))
+                storeart.emit("finished")
                 return
 
             if queried_media is None:
                 return
 
             self._async_queue.queue(
-                StoreArt(), corealbum, queried_media.get_thumbnail(),
+                storeart, corealbum, queried_media.get_thumbnail(),
                 CoreObjectType.ALBUM)
 
         album_id: str = media.get_id()
@@ -1250,12 +1254,14 @@ class GrlTrackerWrapper(GObject.GObject):
             query, self._METADATA_THUMBNAIL_KEYS, self._full_options_lprio,
             art_retrieved_cb)
 
-    def get_artist_art(self, coreartist: CoreArtist) -> None:
+    def get_artist_art(
+            self, coreartist: CoreArtist, storeart: StoreArt) -> None:
         """Retrieve artist art for the given CoreArtist
 
         This retrieves art through Grilo online services only.
 
         :param CoreArtist coreartist: CoreArtist to get art for
+        :param StoreArt storeart: StoreArt instance to use
         """
         media: Grl.Media = coreartist.props.media
 
@@ -1264,14 +1270,21 @@ class GrlTrackerWrapper(GObject.GObject):
                 resolved_media: Optional[Grl.Media],
                 error: Optional[GLib.Error]) -> None:
             if error:
+                storeart.emit("finished")
                 self._log.warning("Error: {}".format(error))
                 return
 
             if resolved_media is None:
+                storeart.emit("finished")
+                return
+
+            thumbnail = resolved_media.get_thumbnail()
+            if thumbnail is None:
+                storeart.emit("finished")
                 return
 
             self._async_queue.queue(
-                StoreArt(), coreartist, resolved_media.get_thumbnail(),
+                storeart, coreartist, resolved_media.get_thumbnail(),
                 CoreObjectType.ARTIST)
 
         self.props.source.resolve(
diff --git a/gnomemusic/songart.py b/gnomemusic/songart.py
index 4058aa0cc..b5686ecff 100644
--- a/gnomemusic/songart.py
+++ b/gnomemusic/songart.py
@@ -29,6 +29,8 @@ from gi.repository import GObject, MediaArt
 from gnomemusic.asyncqueue import AsyncQueue
 from gnomemusic.embeddedart import EmbeddedArt
 from gnomemusic.fileexistsasync import FileExistsAsync
+from gnomemusic.storeart import StoreArt
+from gnomemusic.utils import CoreObjectType
 
 
 class SongArt(GObject.GObject):
@@ -56,7 +58,7 @@ class SongArt(GObject.GObject):
         if found:
             self._in_cache()
         else:
-            self._coregrilo.get_song_art(self._coresong)
+            self._coregrilo.get_song_art(self._coresong, StoreArt())
 
     def _in_cache(self):
         success, thumb_file = MediaArt.get_file(


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]