diff --git a/mopidy/core.py b/mopidy/core.py index f54a3826..69760094 100644 --- a/mopidy/core.py +++ b/mopidy/core.py @@ -1,6 +1,7 @@ import logging import multiprocessing import optparse +import sys from mopidy import get_version, settings, OptionalDependencyError from mopidy.utils import get_class @@ -80,7 +81,9 @@ class CoreProcess(BaseThread): return frontends def process_message(self, message): - if message.get('to') == 'output': + if message.get('to') == 'core': + self.process_message_to_core(message) + elif message.get('to') == 'output': self.output.process_message(message) elif message.get('to') == 'frontend': for frontend in self.frontends: @@ -93,3 +96,12 @@ class CoreProcess(BaseThread): self.backend.stored_playlists.playlists = message['playlists'] else: logger.warning(u'Cannot handle message: %s', message) + + def process_message_to_core(self, message): + assert message['to'] == 'core', u'Message recipient must be "core".' + if message['command'] == 'exit': + if message['reason'] is not None: + logger.info(u'Exiting (%s)', message['reason']) + sys.exit(message['status']) + else: + logger.warning(u'Cannot handle message: %s', message) diff --git a/mopidy/utils/process.py b/mopidy/utils/process.py index e4ef2484..9af6fbf5 100644 --- a/mopidy/utils/process.py +++ b/mopidy/utils/process.py @@ -28,17 +28,17 @@ class BaseProcess(multiprocessing.Process): try: self.run_inside_try() except KeyboardInterrupt: - logger.info(u'%s: Interrupted by user', self.name) - sys.exit(0) + logger.info(u'Interrupted by user') + self.exit(0, u'Interrupted by user') except SettingsError as e: logger.error(e.message) - sys.exit(1) + self.exit(1, u'Settings error') except ImportError as e: logger.error(e) - sys.exit(1) + self.exit(2, u'Import error') except Exception as e: logger.exception(e) - raise e + self.exit(3, u'Unknown error') def run_inside_try(self): raise NotImplementedError @@ -46,6 +46,11 @@ class BaseProcess(multiprocessing.Process): def destroy(self): self.terminate() + def exit(self, status=0, reason=None): + self.core_queue.put({'to': 'core', 'command': 'exit', + 'status': status, 'reason': reason}) + self.destroy() + class BaseThread(multiprocessing.dummy.Process): def __init__(self, core_queue): @@ -57,20 +62,25 @@ class BaseThread(multiprocessing.dummy.Process): try: self.run_inside_try() except KeyboardInterrupt: - logger.info(u'%s: Interrupted by user', self.name) - sys.exit(0) + logger.info(u'Interrupted by user') + self.exit(0, u'Interrupted by user') except SettingsError as e: logger.error(e.message) - sys.exit(1) + self.exit(1, u'Settings error') except ImportError as e: logger.error(e) - sys.exit(1) + self.exit(2, u'Import error') except Exception as e: logger.exception(e) - raise e + self.exit(3, u'Unknown error') def run_inside_try(self): raise NotImplementedError def destroy(self): pass + + def exit(self, status=0, reason=None): + self.core_queue.put({'to': 'core', 'command': 'exit', + 'status': status, 'reason': reason}) + self.destroy()