scanner: Create a TaskQueue
For running tasks with a GLib idle callback Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
parent
da78887783
commit
a102087ece
|
@ -1,3 +1,4 @@
|
|||
# Copyright 2021 (c) Anna Schumaker.
|
||||
from . import metadata
|
||||
from . import queue
|
||||
from . import task
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# Copyright 2021 (c) Anna Schumaker.
|
||||
from gi.repository import GLib
|
||||
from gi.repository import GObject
|
||||
from . import task
|
||||
|
||||
class TaskQueue(GObject.GObject):
|
||||
def __init__(self):
|
||||
GObject.GObject.__init__(self)
|
||||
self.tasks = [ ]
|
||||
self.total = 0
|
||||
self.idleid = None
|
||||
|
||||
def __del__(self):
|
||||
if self.idleid != None:
|
||||
GLib.source_remove(self.idleid)
|
||||
|
||||
def push(self, task):
|
||||
self.emit("task-pushed", task)
|
||||
|
||||
def run(self):
|
||||
self.emit("run-task", self.tasks.pop(0))
|
||||
if len(self.tasks) > 0:
|
||||
return GLib.SOURCE_CONTINUE
|
||||
|
||||
self.emit("tasks-finished")
|
||||
return GLib.SOURCE_REMOVE
|
||||
|
||||
@GObject.Property
|
||||
def progress(self):
|
||||
if len(self.tasks) == 0:
|
||||
return 0
|
||||
return (self.total - len(self.tasks)) / self.total
|
||||
|
||||
@GObject.Signal(arg_types=(task.Task,))
|
||||
def task_pushed(self, task):
|
||||
self.tasks.append(task)
|
||||
self.total += 1
|
||||
if self.idleid == None:
|
||||
self.idleid = GLib.idle_add(self.run)
|
||||
|
||||
@GObject.Signal(arg_types=(task.Task,))
|
||||
def run_task(self, task):
|
||||
if tasks := task.run_task():
|
||||
self.tasks += tasks
|
||||
self.total += len(tasks)
|
||||
|
||||
@GObject.Signal
|
||||
def tasks_finished(self):
|
||||
if self.idleid:
|
||||
GLib.source_remove(self.idleid)
|
||||
self.tasks.clear()
|
||||
self.total = 0
|
||||
self.idleid = None
|
|
@ -0,0 +1,78 @@
|
|||
# Copyright 2021 (c) Anna Schumaker.
|
||||
import unittest
|
||||
from gi.repository import GObject
|
||||
from . import queue
|
||||
from . import task
|
||||
|
||||
class FakeTask(task.Task):
|
||||
def __init__(self, res=None):
|
||||
task.Task.__init__(self)
|
||||
self.res = res
|
||||
def run_task(self): return self.res
|
||||
|
||||
class TestScannerTaskQueue(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.idle_start = None
|
||||
|
||||
def on_task_pushed(self, queue, task):
|
||||
self.pushed_task = task
|
||||
|
||||
def on_run_task(self, queue, task):
|
||||
self.run_task = task
|
||||
|
||||
def on_tasks_finished(self, queue):
|
||||
self.tasks_finished = True
|
||||
|
||||
def test_scanner_queue_init(self):
|
||||
q = queue.TaskQueue()
|
||||
|
||||
self.assertIsInstance(q, GObject.GObject)
|
||||
self.assertEqual(q.tasks, [ ])
|
||||
self.assertEqual(q.total, 0)
|
||||
self.assertEqual(q.idleid, None)
|
||||
self.assertEqual(q.progress, 0)
|
||||
|
||||
def test_scanner_queue_push(self):
|
||||
q = queue.TaskQueue()
|
||||
fake = FakeTask()
|
||||
q.connect("task-pushed", self.on_task_pushed)
|
||||
|
||||
q.push(fake)
|
||||
self.assertEqual(q.tasks, [ fake ])
|
||||
self.assertIsNotNone(q.idleid)
|
||||
self.assertEqual(self.pushed_task, fake)
|
||||
|
||||
def test_scanner_queue_run(self):
|
||||
q = queue.TaskQueue()
|
||||
fake3 = FakeTask()
|
||||
fake2 = FakeTask()
|
||||
fake1 = FakeTask([ fake2, fake3 ])
|
||||
q.connect("run-task", self.on_run_task)
|
||||
q.connect("tasks-finished", self.on_tasks_finished)
|
||||
|
||||
q.push(fake1)
|
||||
self.assertEqual(q.tasks, [ fake1 ])
|
||||
self.assertEqual(q.total, 1)
|
||||
self.assertEqual(q.progress, 0/1)
|
||||
|
||||
q.run()
|
||||
self.assertEqual(self.run_task, fake1)
|
||||
self.assertEqual(q.tasks, [ fake2, fake3 ])
|
||||
self.assertEqual(q.total, 3)
|
||||
self.assertEqual(q.progress, 1/3)
|
||||
self.assertIsNotNone(q.idleid)
|
||||
|
||||
q.run()
|
||||
self.assertEqual(self.run_task, fake2)
|
||||
self.assertEqual(q.tasks, [ fake3 ])
|
||||
self.assertEqual(q.progress, 2/3)
|
||||
self.assertIsNotNone(q.idleid)
|
||||
|
||||
q.run()
|
||||
self.assertEqual(self.run_task, fake3)
|
||||
self.assertEqual(q.tasks, [ ])
|
||||
|
||||
self.assertTrue(self.tasks_finished)
|
||||
self.assertEqual(q.total, 0)
|
||||
self.assertEqual(q.progress, 0)
|
||||
self.assertIsNone(q.idleid)
|
Loading…
Reference in New Issue