[gnome-music/wip/gbsneto/playlists: 7/7] playlists: use the async variants of the blocking calls



commit ca381cb0315dabb056eb0d8874a837013f915426
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 |   44 +++++++++++++++++++++++++++++++-------------
 1 files changed, 31 insertions(+), 13 deletions(-)
---
diff --git a/gnomemusic/playlists.py b/gnomemusic/playlists.py
index 77158e1..2e3cb12 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,48 @@ 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)
+        cursor = self.tracker.query_finish(res)
         if not cursor:
             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)
+            if cursor.next_finish(res):
+                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]