python-mpd2
python-mpd2 copied to clipboard
Asynchronous idle
Is there still a way to, without going through private APIs, send the idle command and not wait for its results? The docs mention send_idle/fetch_idle, but I see the support for them was deprecated in f3864acbfcaa0c67507d3fa01fe0118b2cf19dc5 and removed in 3a734547e753f9cde139cc74925e7320bff67b7a. The changelog lists asyncio and twisted as alternatives, but these are not an option for us as we're already dealing with the Qt event loop: pulling in asyncio on top would be a tremendous burden.
@aurieh just as a comment - I'm using PySide2 (Qt5 for now) and asyncio and python-mpd2 quite happily with https://github.com/CabbageDevelopment/qasync The same python/Qt application also interacts with Django async code and the async MQTT implementation here https://github.com/wialon/gmqtt
Overall I don't find it at all burdensome to use asyncio with Qt (it actually fits very nicely indeed)
The reason I'm here btw is because I've started an asyncio listen task (on a QObject method):
class Player(QObject):
...
async def initialise(self):
# QObjects are created non-async so you need to do async initialisation in an await qobj.initialise()
await self._connect()
status = await self._mpd.status()
await self.handle_status(status)
self._listen_task = asyncio.create_task(self.listen())
....
async def listen(self):
while not self._stop_event.is_set():
while True:
try:
await self._connect()
except Exception as e:
logger.debug("_connect failed")
if self._mpd.connected:
break
logger.debug('Connect failed. Trying again in 1s')
await asyncio.sleep(1)
try:
async for subsystem in self._mpd.idle():
logger.debug(f"Idle change in {subsystem})")
await self.update_status()
if "player" in subsystem:
await self.get_mpd_songinfo()
except Exception as e:
logger.debug("Caught %s", e)
But sometimes I lose the mpd connection and the async mdp.idle() does not notice and therefore does not exit allow a reconnection to occur.
In the asyncio variant usually after a timeout, the library switches to an "idle" mode: https://github.com/Mic92/python-mpd2/blob/9161f301fab9b1cdc596b787544e4cfb3d0a53f0/mpd/asyncio.py#L302 This is to prevent MPD from closing the connection, which it does if there is no activity.
But it is unclear to me why "idle()" doesn't pick up if the connection is lost.
OK, old thread I know but on a related topic... I have the 'idle' state working fine after sending idle() command in a separate thread and MPD reports changes as they occur, BUT how can I exit the idle state before a player change occurs? The noidle() command returns an exception... from asyncio.py [670 raise AttributeError("noidle is not supported / required in mpd.asyncio")] so what is supported or required? Any help from those in the know would be gratefully received.
Please forget/forgive my previous comment/query. Looking at your asyncio.py code again in the morning with a clearer head I now see what I need to do.