[gnome-music/wip/mschraal/file-exists-async: 49/53] asyncqueue: Add adaptive queueing
- From: Marinus Schraal <mschraal src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/mschraal/file-exists-async: 49/53] asyncqueue: Add adaptive queueing
- Date: Sun, 29 Aug 2021 09:06:53 +0000 (UTC)
commit 7831cf188dc8090d197691d18b24f3cf5323fa80
Author: Marinus Schraal <mschraal gnome org>
Date: Tue Aug 17 16:25:00 2021 +0200
asyncqueue: Add adaptive queueing
Provide adaptive queueing, which throttles the amount of concurrent
async tasks based on earlier timings.
This is mainly meant for local I/O based tasks as the timings may
indicate bottlenecks.
gnomemusic/albumart.py | 2 +-
gnomemusic/artistart.py | 2 +-
gnomemusic/asyncqueue.py | 23 ++++++++++++++++++++++-
gnomemusic/songart.py | 2 +-
gnomemusic/widgets/artstack.py | 2 +-
5 files changed, 26 insertions(+), 5 deletions(-)
---
diff --git a/gnomemusic/albumart.py b/gnomemusic/albumart.py
index 7a8f6a12a..fc5d4ce39 100644
--- a/gnomemusic/albumart.py
+++ b/gnomemusic/albumart.py
@@ -35,7 +35,7 @@ class AlbumArt(GObject.GObject):
"""AlbumArt retrieval object
"""
- _async_queue = AsyncQueue("AlbumArt")
+ _async_queue = AsyncQueue("AlbumArt", True)
def __init__(self, application, corealbum):
"""Initialize AlbumArt
diff --git a/gnomemusic/artistart.py b/gnomemusic/artistart.py
index 04d913c76..ec95fd8b0 100644
--- a/gnomemusic/artistart.py
+++ b/gnomemusic/artistart.py
@@ -34,7 +34,7 @@ class ArtistArt(GObject.GObject):
"""Artist art retrieval object
"""
- _async_queue = AsyncQueue("ArtistArt")
+ _async_queue = AsyncQueue("ArtistArt", True)
def __init__(self, application, coreartist):
"""Initialize.
diff --git a/gnomemusic/asyncqueue.py b/gnomemusic/asyncqueue.py
index 125b2145f..6843a63b5 100644
--- a/gnomemusic/asyncqueue.py
+++ b/gnomemusic/asyncqueue.py
@@ -22,6 +22,7 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
+from collections import deque
from typing import Any, Dict, Optional, Tuple
import time
@@ -46,19 +47,25 @@ class AsyncQueue(GObject.GObject):
may have an arbitrary number of arguments following.
"""
- def __init__(self, queue_name: Optional[str] = None) -> None:
+ def __init__(
+ self, queue_name: Optional[str] = None,
+ adaptive: bool = False) -> None:
"""Initialize AsyncQueue
:param str queue_name: The user facing name of this queue or
None for the generic class identifier
+ :param bool adaptive: Allow adapting the queue size based on
+ timing information
"""
super().__init__()
+ self._adaptive = adaptive
self._async_pool: Dict[int, Tuple] = {}
self._async_active_pool: Dict[int, Tuple] = {}
self._log = MusicLogger()
self._max_async = 4
self._queue_name = queue_name if queue_name else self
+ self._timings = deque([0.0], 10)
def queue(self, *args: Any) -> None:
"""Queue an async call
@@ -89,6 +96,9 @@ class AsyncQueue(GObject.GObject):
f"{self._queue_name}: "
f"{a} active task(s) of {len(self._async_pool) + a}")
+ if self._adaptive:
+ self._adapt_queue_size(t)
+
obj.disconnect(result_id)
self._async_active_pool.pop(id(obj))
@@ -104,3 +114,14 @@ class AsyncQueue(GObject.GObject):
result_id = async_obj.connect("finished", on_async_finished)
async_obj.start(*async_task_args[1:])
+
+ def _adapt_queue_size(self, timing: float) -> None:
+ avg_time = sum(self._timings) / len(self._timings)
+ if avg_time > timing * 1.25:
+ self._max_async -= 1
+ self._max_async = max(1, self._max_async)
+ elif avg_time < timing * 0.75:
+ self._max_async += 1
+ self._max_async = min(10, self._max_async)
+
+ self._timings.append(timing)
diff --git a/gnomemusic/songart.py b/gnomemusic/songart.py
index 94bf46c90..b18a9d10e 100644
--- a/gnomemusic/songart.py
+++ b/gnomemusic/songart.py
@@ -35,7 +35,7 @@ class SongArt(GObject.GObject):
"""SongArt retrieval object
"""
- _async_queue = AsyncQueue("SongArt")
+ _async_queue = AsyncQueue("SongArt", True)
def __init__(self, application, coresong):
"""Initialize SongArt
diff --git a/gnomemusic/widgets/artstack.py b/gnomemusic/widgets/artstack.py
index 0c0b9d379..7439bfb2c 100644
--- a/gnomemusic/widgets/artstack.py
+++ b/gnomemusic/widgets/artstack.py
@@ -40,7 +40,7 @@ class ArtStack(Gtk.Stack):
__gtype_name__ = "ArtStack"
- _async_queue = AsyncQueue("ArtStack")
+ _async_queue = AsyncQueue("ArtStack", True)
def __init__(self, size: ArtSize = ArtSize.MEDIUM) -> None:
"""Initialize the ArtStack
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]