From ba12d0ac2cdf407f981751ad451674bd6ae7b391 Mon Sep 17 00:00:00 2001 From: williamvds Date: Fri, 29 Dec 2023 12:37:47 +0000 Subject: [PATCH] Add --managed option to disable timer When idle is available, the main purpose of the timer loop is to reconnect the socket when it is disconnected. An alternative is to allow systemd to handle this for us. We can bind the daemon to the mpd service, so that it is started automatically with the mpd service. Add a new command-line option `--managed`. If this is set, the daemon will exit cleanly instead of attempting a reconnect loop, under the assmption that systemd will restart it when mpd is available again. --- src/mpDris2.in.py | 44 +++++++++++++++++++++++++++++++----------- src/mpDris2.service.in | 6 ++++-- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/mpDris2.in.py b/src/mpDris2.in.py index a07793d..13cf591 100755 --- a/src/mpDris2.in.py +++ b/src/mpDris2.in.py @@ -64,6 +64,7 @@ 'port': None, 'password': None, 'bus_name': None, + 'managed': False, # Library 'music_dir': '', 'cover_regex': None, @@ -242,6 +243,7 @@ def __init__(self, params): self._dbus = dbus self._params = params self._dbus_service = None + self._should_reconnect = not params['managed'] self._can_single = False self._can_idle = False @@ -328,8 +330,10 @@ def my_connect(self): # Init internal state to throw events at start self.init_state() - # Add periodic status check for sending MPRIS events - if not self._poll_id: + # If idle is not available, add periodic status check for sending MPRIS events + # Otherwise the timer will connect the socket if disconnected + # If reconnection is not necessary and idle is supported, this timer isn't enabled. + if not self._poll_id and (not self._can_idle or self._should_reconnect): interval = 15 if self._can_idle else 1 self._poll_id = GLib.timeout_add_seconds(interval, self.timer_callback) @@ -436,13 +440,27 @@ def timer_callback(self): def socket_callback(self, fd, event): logger.debug("Socket event %r on fd %r" % (event, fd)) - if event & GLib.IO_HUP: - self.reconnect() + + def handle_disconnect(): + if self._should_reconnect: + self.reconnect() + else: + logger.debug("Not reconnecting, quitting main loop") + loop.quit() return True + + if event & GLib.IO_HUP: + return handle_disconnect() + elif event & GLib.IO_IN: if self._idling: self._idling = False - data = fd._fetch_objects("changed") + + try: + data = fd._fetch_objects("changed") + except mpd.base.ConnectionError: + return handle_disconnect() + logger.debug("Idle events: %r" % data) updated = False for item in data: @@ -1394,6 +1412,7 @@ def usage(params): ['help', 'bus-name=', 'config=', 'debug', 'host=', 'music-dir=', 'use-journal', 'path=', 'port=', + 'managed', 'version']) except getopt.GetoptError as ex: (msg, opt) = ex.args @@ -1420,6 +1439,8 @@ def usage(params): music_dir = arg elif opt in ['--port']: params['port'] = int(arg) + elif opt in ['--managed']: + params['managed'] = True elif opt in ['-v', '--version']: v = __version__ if __git_version__: @@ -1564,9 +1585,10 @@ def usage(params): logger.debug('Caught SIGINT, exiting.') # Clean up - try: - mpd_wrapper.client.close() - mpd_wrapper.client.disconnect() - logger.debug('Exiting') - except mpd.ConnectionError: - logger.error('Failed to disconnect properly') + if mpd_wrapper.connected: + try: + mpd_wrapper.client.close() + mpd_wrapper.client.disconnect() + logger.debug('Exiting') + except mpd.ConnectionError: + logger.error('Failed to disconnect properly') diff --git a/src/mpDris2.service.in b/src/mpDris2.service.in index b612804..d6deab2 100644 --- a/src/mpDris2.service.in +++ b/src/mpDris2.service.in @@ -1,11 +1,13 @@ [Unit] Description=mpDris2 - Music Player Daemon D-Bus bridge +Wants=mpd.service +BindsTo=mpd.service [Service] Restart=on-failure -ExecStart=@bindir@/mpDris2 --use-journal +ExecStart=@bindir@/mpDris2 --use-journal --managed BusName=org.mpris.MediaPlayer2.mpd [Install] WantedBy=default.target -# WantedBy=daemon.target +WantedBy=mpd.service