Skip to content

Asynchronous idle #194

Open
Open

Description

@aurieh

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 f3864ac and removed in 3a73454. 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.

Activity

  1. lbt commented on Sep 3, 2022

    @lbt
    Contributor

    @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.

  2. Mic92 commented on Jan 14, 2024

    @Mic92
    Owner

    In the asyncio variant usually after a timeout, the library switches to an "idle" mode:

    timeout=self.IMMEDIATE_COMMAND_TIMEOUT,

    This is to prevent MPD from closing the connection, which it does if there is no activity.

  3. Mic92 commented on Jan 14, 2024

    @Mic92
    Owner

    But it is unclear to me why "idle()" doesn't pick up if the connection is lost.

  4. 21stCent commented on Feb 12, 2024

    @21stCent

    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.

  5. 21stCent commented on Feb 14, 2024

    @21stCent

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions