Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asynchronous idle #194

Open
aurieh opened this issue Jun 2, 2022 · 5 comments
Open

Asynchronous idle #194

aurieh opened this issue Jun 2, 2022 · 5 comments

Comments

@aurieh
Copy link
Contributor

aurieh commented Jun 2, 2022

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.

@lbt
Copy link
Contributor

lbt commented Sep 3, 2022

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

@Mic92
Copy link
Owner

Mic92 commented Jan 14, 2024

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.

@Mic92
Copy link
Owner

Mic92 commented Jan 14, 2024

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

@21stCent
Copy link

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.

@21stCent
Copy link

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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants