I'm using the python-mpd2 module to control a media player on a Raspberry Pi in a GUI application. Thus, I'd like to gracefully handle connection errors and timeouts (the player in question drops MPD connections after 60 seconds) in the background. However, the MPD module has no single point of entry through which all commands are sent or information is retrieved that I could patch.
I'd like a class which allows access to all of the same methods as mpd.MPDClient, but let's me add my own error handling. In other words, if I do:
client.play()
And a connectione error is thrown, I'd like to catch it and resend the same command. Other than the small delay caused by having to reconnect to the server, the user shouldn't notice that anything is amiss.
So far, here is the solution I've come up with. It is working in my application, but doesn't really fulfill my objectives.
from functools import partial
from mpd import MPDClient, ConnectionError
class PersistentMPDClient(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.client = MPDClient()
self.client.connect(self.host, self.port)
def command(self, cmd, *args, **kwargs):
command_callable = partial(self.client.__getattribute__(cmd), *args, **kwargs)
try:
return command_callable()
except ConnectionError:
# Mopidy drops our connection after a while, so reconnect to send the command
self.client._soc = None
self.client.connect(self.host, self.port)
return command_callable()
I could add a method to this class for every single MPD command, e.g.:
def play(self):
return self.command("play")
But this seems far from the best way to accomplish it.