[gnome-music] playlists: Use the async variants of the blocking calls



commit ca7fd3a33de17999918bf36e6e95d0c098e85f76
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Tue Oct 4 18:18:31 2016 -0300

    playlists: Use the async variants of the blocking calls
    
    When loading or updating the static playlists, the entire callchain
    uses the synchronous, main context blocking variants of the Tracker
    API. This leads to an unresponsive GNOME Music, specially at the
    startup.
    
    Fix that by using the async variants of the Tracker API throughout the
    static playlists building chain.

 gnomemusic/playlists.py |   55 +++++++++++++++++++++++++++++++++++------------
 1 files changed, 41 insertions(+), 14 deletions(-)
---
diff --git a/gnomemusic/playlists.py b/gnomemusic/playlists.py
index 77158e1..f8e6148 100644
--- a/gnomemusic/playlists.py
+++ b/gnomemusic/playlists.py
@@ -150,11 +150,6 @@ class Playlists(GObject.GObject):
                 callback, playlist)
 
     @log
-    def clear_playlist_with_id(self, playlist_id):
-        query = Query.clear_playlist_with_id(playlist_id)
-        self.tracker.update(query, GLib.PRIORITY_LOW, None)
-
-    @log
     def update_playcount(self, song_url):
         query = Query.update_playcount(song_url)
         self.tracker.update(query, GLib.PRIORITY_LOW, None)
@@ -169,25 +164,57 @@ class Playlists(GObject.GObject):
     def update_static_playlist(self, playlist):
         """Given a static playlist (subclass of StaticPlaylists), updates according to its query."""
         # Clear the playlist
-        self.clear_playlist_with_id(playlist.ID)
+        self.clear_playlist(playlist)
 
+    @log
+    def clear_playlist(self, playlist):
+        """Starts cleaning the playlist"""
+        query = Query.clear_playlist_with_id(playlist.ID)
+        self.tracker.update_async(query, GLib.PRIORITY_LOW, None,
+                                  self._static_playlist_cleared_cb, playlist)
+
+    @log
+    def _static_playlist_cleared_cb(self, connection, res, playlist):
+        """After clearing the playlist, start querying the playlist's songs"""
+        # Get a list of matching songs
+        self.tracker.query_async(playlist.QUERY, None,
+                                 self._static_playlist_query_cb, playlist)
+
+    @log
+    def _static_playlist_query_cb(self, connection, res, playlist):
+        """Fetch the playlist's songs"""
         final_query = ''
 
         # Get a list of matching songs
-        cursor = self.tracker.query(playlist.QUERY, None)
-        if not cursor:
+        try:
+            cursor = self.tracker.query_finish(res)
+        except GLib.Error as err:
+            logger.warn("Error: %s, %s", err.__class__, err)
             return
 
-        # For each song run 'add song to playlist'
-        while cursor.next():
+        def callback(conn, res, final_query):
             uri = cursor.get_string(0)[0]
             final_query += Query.add_song_to_playlist(playlist.ID, uri)
 
-        self.tracker.update_blank_async(final_query, GLib.PRIORITY_LOW,
-                                        None, None, None)
+            try:
+                has_next = cursor.next_finish(res)
+            except GLib.Error as err:
+                logger.warn("Error: %s, %s", err.__class__, err)
+                has_next = False
+
+            # Only perform the update when the cursor reached the end
+            if has_next:
+                cursor.next_async(None, callback, final_query)
+                return
+
+            self.tracker.update_blank_async(final_query, GLib.PRIORITY_LOW,
+                                            None, None, None)
+
+            # tell system we updated the playlist so playlist is reloaded
+            self.emit('playlist-updated', playlist.ID)
 
-        # tell system we updated the playlist so playlist is reloaded
-        self.emit('playlist-updated', playlist.ID)
+        # Asynchronously form the playlist's final query
+        cursor.next_async(None, callback, final_query)
 
     @log
     def update_all_static_playlists(self):


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