From c128668621c0d007a488ea7275f255bd254d0c97 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 26 Nov 2013 15:10:48 +0100 Subject: [PATCH 1/2] listeners: Make listeners async - Add a common Listener base class - Make send helper for sending out events with pykka - Make send async helper for avoiding blocking events This change ensures all the events now get sent out via the MainThread instead of blocking the actors. --- mopidy/audio/listener.py | 24 +++--------------------- mopidy/backends/listener.py | 21 +++------------------ mopidy/core/listener.py | 8 +++----- mopidy/listener.py | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 44 deletions(-) create mode 100644 mopidy/listener.py diff --git a/mopidy/audio/listener.py b/mopidy/audio/listener.py index 464407b4..537a81dd 100644 --- a/mopidy/audio/listener.py +++ b/mopidy/audio/listener.py @@ -1,9 +1,9 @@ from __future__ import unicode_literals -import pykka +from mopidy import listener -class AudioListener(object): +class AudioListener(listener.Listener): """ Marker interface for recipients of events sent by the audio actor. @@ -17,25 +17,7 @@ class AudioListener(object): @staticmethod def send(event, **kwargs): """Helper to allow calling of audio listener events""" - listeners = pykka.ActorRegistry.get_by_class(AudioListener) - for listener in listeners: - listener.proxy().on_event(event, **kwargs) - - def on_event(self, event, **kwargs): - """ - Called on all events. - - *MAY* be implemented by actor. By default, this method forwards the - event to the specific event methods. - - For a list of what event names to expect, see the names of the other - methods in :class:`AudioListener`. - - :param event: the event name - :type event: string - :param kwargs: any other arguments to the specific event handlers - """ - getattr(self, event)(**kwargs) + listener.send_async(AudioListener, event, **kwargs) def reached_end_of_stream(self): """ diff --git a/mopidy/backends/listener.py b/mopidy/backends/listener.py index d9043079..ee4735e7 100644 --- a/mopidy/backends/listener.py +++ b/mopidy/backends/listener.py @@ -1,9 +1,9 @@ from __future__ import unicode_literals -import pykka +from mopidy import listener -class BackendListener(object): +class BackendListener(listener.Listener): """ Marker interface for recipients of events sent by the backend actors. @@ -19,22 +19,7 @@ class BackendListener(object): @staticmethod def send(event, **kwargs): """Helper to allow calling of backend listener events""" - listeners = pykka.ActorRegistry.get_by_class(BackendListener) - for listener in listeners: - listener.proxy().on_event(event, **kwargs) - - def on_event(self, event, **kwargs): - """ - Called on all events. - - *MAY* be implemented by actor. By default, this method forwards the - event to the specific event methods. - - :param event: the event name - :type event: string - :param kwargs: any other arguments to the specific event handlers - """ - getattr(self, event)(**kwargs) + listener.send_async(BackendListener, event, **kwargs) def playlists_loaded(self): """ diff --git a/mopidy/core/listener.py b/mopidy/core/listener.py index 40c78540..f0bb1ea3 100644 --- a/mopidy/core/listener.py +++ b/mopidy/core/listener.py @@ -1,9 +1,9 @@ from __future__ import unicode_literals -import pykka +from mopidy import listener -class CoreListener(object): +class CoreListener(listener.Listener): """ Marker interface for recipients of events sent by the core actor. @@ -17,9 +17,7 @@ class CoreListener(object): @staticmethod def send(event, **kwargs): """Helper to allow calling of core listener events""" - listeners = pykka.ActorRegistry.get_by_class(CoreListener) - for listener in listeners: - listener.proxy().on_event(event, **kwargs) + listener.send_async(CoreListener, event, **kwargs) def on_event(self, event, **kwargs): """ diff --git a/mopidy/listener.py b/mopidy/listener.py new file mode 100644 index 00000000..6461e0e5 --- /dev/null +++ b/mopidy/listener.py @@ -0,0 +1,33 @@ +from __future__ import unicode_literals + +import gobject +import logging +import pykka + +logger = logging.getLogger('mopidy.listener') + + +def send_async(cls, event, **kwargs): + gobject.idle_add(lambda: send(cls, event, **kwargs)) + + +def send(cls, event, **kwargs): + listeners = pykka.ActorRegistry.get_by_class(cls) + logger.debug('Sending %s to %s: %s', event, cls.__name__, kwargs) + for listener in listeners: + listener.proxy().on_event(event, **kwargs) + + +class Listener(object): + def on_event(self, event, **kwargs): + """ + Called on all events. + + *MAY* be implemented by actor. By default, this method forwards the + event to the specific event methods. + + :param event: the event name + :type event: string + :param kwargs: any other arguments to the specific event handlers + """ + getattr(self, event)(**kwargs) From 9e1d46a661ffcfab1a226c43af1074bb5d296413 Mon Sep 17 00:00:00 2001 From: Thomas Adamcik Date: Tue, 26 Nov 2013 16:04:21 +0100 Subject: [PATCH 2/2] listeners: Import grouping fix --- mopidy/listener.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mopidy/listener.py b/mopidy/listener.py index 6461e0e5..715beb03 100644 --- a/mopidy/listener.py +++ b/mopidy/listener.py @@ -1,7 +1,8 @@ from __future__ import unicode_literals -import gobject import logging + +import gobject import pykka logger = logging.getLogger('mopidy.listener')