curds: Improve queueing notifications

The UI might take a while to process queued notifications, so to keep
from overwhelming the UI we want to only queue notification that haven't
been added already.

I also add in a lock around the notification queue since the main thread
processes notifications added by other threads.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2019-04-05 13:35:57 -04:00
parent 56f7930032
commit 0e6b788af1
3 changed files with 55 additions and 20 deletions

View File

@ -1,13 +1,17 @@
# Copyright 2019 (c) Anna Schumaker.
import threading
registered = { }
queued = [ ]
lock = threading.Lock()
def notify(name, *args):
for (func, queue) in registered.get(name, []):
if queue == True:
queued.append((func, args))
notify("task-queued")
with lock:
if (func, args) not in queued:
queued.append((func, args))
notify("task-queued")
else:
func(*args)
@ -25,7 +29,8 @@ def register(name, func, queue=False):
cb.append((func, queue))
def run_queued():
if len(queued) > 0:
(func, args) = queued.pop(0)
func(*args)
return len(queued) > 0
with lock:
if len(queued) > 0:
(func, args) = queued.pop(0)
func(*args)
return len(queued) > 0

View File

@ -14,6 +14,7 @@ class TestLibraryPlaylist(unittest.TestCase):
def setUp(self):
library.reset()
tags.clear()
notify.registered.clear()
def tearDownClass():
library.stop()

View File

@ -11,14 +11,16 @@ class TestNotify(unittest.TestCase):
self.test_arg2 = None
self.task_queued = False
def on_test1(self, arg1, arg2):
self.test_count += 1
def on_test2(self, arg1, arg2):
self.test_arg1 = arg1
def on_test3(self, arg1, arg2):
self.test_arg2 = arg2
def on_queued(self):
self.task_queued = True
def tearDown(self):
notify.queued.clear()
notify.registered.clear()
def on_test1(self, arg1, arg2): self.test_count += 1
def on_test2(self, arg1, arg2): self.test_arg1 = arg1
def on_test3(self, arg1, arg2): self.test_arg2 = arg2
def on_task_queued(self): self.task_queued = True
def on_test_queue(self, arg1): self.test_count += 1; self.test_arg1 = arg1
def test_notify(self):
self.assertEqual(notify.registered, {})
@ -29,17 +31,14 @@ class TestNotify(unittest.TestCase):
notify.register("on-test", self.on_test1, True)
notify.register("on-test", self.on_test2)
notify.register("on-test", self.on_test3, True)
notify.register("task-queued", self.on_queued)
self.assertEqual(notify.registered, {"on-test" : [ (self.on_test1, False),
(self.on_test2, False),
(self.on_test3, True ) ],
"task-queued" : [ (self.on_queued, False) ]})
(self.on_test3, True ) ]})
notify.notify("on-test", "It Worked", "CoolCoolCool")
self.assertEqual(self.test_count, 1)
self.assertEqual(self.test_arg1, "It Worked")
self.assertEqual(self.test_arg2, None)
self.assertTrue(self.task_queued)
self.assertEqual(notify.queued, [ (self.on_test3, ("It Worked", "CoolCoolCool")) ])
self.assertFalse(notify.run_queued())
@ -49,8 +48,7 @@ class TestNotify(unittest.TestCase):
notify.notify("no-cb", "Please", "Don't", "Crash")
self.assertFalse(notify.run_queued())
notify.cancel("task-queued", self.on_queued)
notify.cancel("on-test", self.on_test2)
notify.cancel("on-test", self.on_test2)
self.assertEqual(notify.registered, {"on-test" : [ (self.on_test1, False),
(self.on_test3, True) ]})
notify.cancel("on-test", self.on_test1)
@ -59,3 +57,34 @@ class TestNotify(unittest.TestCase):
self.assertEqual(notify.registered, { })
notify.cancel("on-test", self.on_test1)
self.assertEqual(notify.registered, { })
def test_queue(self):
notify.register("task-queued", self.on_task_queued)
notify.register("on-test", self.on_test_queue, True)
self.assertEqual(notify.registered, {"on-test" : [ (self.on_test_queue, True) ],
"task-queued" : [ (self.on_task_queued, False) ]})
notify.notify("on-test", "Test Bundle")
self.assertTrue(self.task_queued)
self.assertEqual(notify.queued, [ (self.on_test_queue, ("Test Bundle",)) ])
self.task_queued = False
notify.notify("on-test", "Test Bundle")
self.assertFalse(self.task_queued)
self.assertEqual(notify.queued, [ (self.on_test_queue, ("Test Bundle",)) ])
notify.notify("on-test", "Test Bundle 2")
self.assertTrue(self.task_queued)
self.assertEqual(notify.queued, [ (self.on_test_queue, ("Test Bundle",)),
(self.on_test_queue, ("Test Bundle 2",)) ])
self.assertTrue(notify.run_queued())
self.assertEqual(self.test_count, 1)
self.assertEqual(self.test_arg1, "Test Bundle")
self.assertEqual(notify.queued, [ (self.on_test_queue, ("Test Bundle 2",)) ])
self.assertFalse(notify.run_queued())
self.assertEqual(self.test_count, 2)
self.assertEqual(self.test_arg1, "Test Bundle 2")
self.assertEqual(notify.queued, [ ])