[gnome-music/wip/gbsneto/artwork-queue] albumartcache: Limit concurrent lookups to 24
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/gbsneto/artwork-queue] albumartcache: Limit concurrent lookups to 24
- Date: Sat, 24 Jun 2017 04:04:59 +0000 (UTC)
commit 742a7c4d7164f2df4b0963d0a3ea9ede1fb4b76f
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sat Jun 24 00:52:20 2017 -0300
albumartcache: Limit concurrent lookups to 24
The current AlbumArtCache implementation does not keep track
of the number of concurrent lookups that are being executed.
When dealing with a small number of items this is acceptable,
but once the number of music items grow, this poses a big
problem. In fact, the biggest bottleneck for when Music is
loading is caused by the thousands of lookups finishing almost
at the same time and overloading GTK+ machinery.
Fix that by introducing a limit to the number of concurrent
lookups being executed. When the limit is hit, the lookups
are queued and executed once a new lookup slot is available.
Notice that downloads are not considered lookups, and file
loading is done in parallel to cover fetching.
gnomemusic/albumartcache.py | 48 ++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 47 insertions(+), 1 deletions(-)
---
diff --git a/gnomemusic/albumartcache.py b/gnomemusic/albumartcache.py
index 4b44d10..c00cd38 100644
--- a/gnomemusic/albumartcache.py
+++ b/gnomemusic/albumartcache.py
@@ -46,6 +46,41 @@ import gnomemusic.utils as utils
logger = logging.getLogger(__name__)
+# Variables shared across instances
+MAX_SIMULTANEOUS_LOOKUPS = 24
+_lookup_queue = []
+_n_lookups = 0
+
+
+@log
+def _push_lookup_counter(cache, item, art_size, callback, itr):
+ """Push a lookup counter or queue the lookup if needed"""
+ global _lookup_queue
+ global _n_lookups
+
+ # If reached the limit, queue the operation
+ if _n_lookups >= MAX_SIMULTANEOUS_LOOKUPS:
+ _lookup_queue.append((cache, item, art_size, callback, itr))
+ return False
+ else:
+ _n_lookups += 1
+ return True
+
+
+@log
+def _pop_lookup_counter():
+ """Pops a lookup counter, and consume the lookup queue if needed"""
+ global _lookup_queue
+ global _n_lookups
+
+ _n_lookups -= 1
+
+ # An available lookup slot appeared! Let's continue looking
+ # up for artwork then
+ if _n_lookups < MAX_SIMULTANEOUS_LOOKUPS and _lookup_queue:
+ (cache, item, art_size, callback, itr) = _lookup_queue.pop(0)
+ cache.lookup(item, art_size, callback, itr)
+
@log
def _make_icon_frame(pixbuf, art_size=None, scale=1):
@@ -235,7 +270,8 @@ class AlbumArtCache(GObject.GObject):
:param callback: Callback function when retrieved
:param itr: Iter to return with callback
"""
- self._lookup_local(item, callback, itr, art_size)
+ if _push_lookup_counter(self, item, art_size, callback, itr):
+ self._lookup_local(item, callback, itr, art_size)
@log
def _lookup_local(self, item, callback, itr, art_size):
@@ -269,6 +305,10 @@ class AlbumArtCache(GObject.GObject):
return
def do_callback(pixbuf):
+
+ # Lookup finished, decrease the counter
+ _pop_lookup_counter()
+
if not pixbuf:
surface = DefaultIcon(self._scale).get(DefaultIcon.Type.music,
art_size)
@@ -298,6 +338,12 @@ class AlbumArtCache(GObject.GObject):
do_callback(None)
return
+ # When we reach here because it fails to retrive the artwork,
+ # well do a long round trip (either through _lookup_embedded or
+ # _lookup_remote) and call self.lookup() again. Thus, decrease
+ # global lookup counter.
+ _pop_lookup_counter()
+
self._lookup_embedded(item, callback, itr, art_size)
@log
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]