Mic92 / python-mpd2

Python library which provides a client interface for the Music Player Daemon.
GNU Lesser General Public License v3.0
352 stars 119 forks source link

asyncio: How to detect when mpd has shut down #155

Closed tjaehnel closed 3 years ago

tjaehnel commented 3 years ago

Hi,

I'm using the asyncio flavor of python-mpd2 and it works very well for me. The one thing I'm struggeling with is the detection of a closed or lost connection.

My code is somehow based on the example from this repository and I'm using idle in the recommended way: async for subsystem in client.idle(): I also set client.timeout = 10 and client.idletimeout = 10.

As long as the connection is alive I perfectly receive all events. But when I shut down my MPD, it just stays there even though python-mpd2 has long since detected the lost connection internally.

The only way to find out about a disconnect seems to send a command. This then throws "ConnectionError: Can not send command to disconnected client" Maybe - according the code - it might also work to check client.__run_task for None.

Unfortunately both solutions involve polling and are not very nice.

Am I missing something? Is there a recommended way to find out about connection loss?

Thank you very much, Toby

Mic92 commented 3 years ago

cc @chrysn

chrysn commented 3 years ago

This looks like an error in the asynchronous iterator -- what it should do is raise a ConnectionError; looking into it.

chrysn commented 3 years ago

Added #156 that raises from the idle iterator if the connection is closed. Other than that, I don't think there'll be need for any notification -- if a program has neither pending commands nor are idling, it's not interested in the connection anyway.

(We might want to consider having a mode of python-mpd2 that eagerly connects, but that'd need timeouts and back-off and what so not, and is just not how mpd2 was designed to work AFAICT.)

chrysn commented 3 years ago

By the way, the timeout and idletimeout parameters pertain to the blocking mode, and do not influence the asynchronous mode. There, the process waits around for a response indefinitely, and only be cancelled if the TCP connection goes down.

tjaehnel commented 3 years ago

Thank you @chrysn for the quick response and fix. Works perfect!

There is no need for automatic reconnection. I'm handling that in my own code as imho that's the correct way to do it.

mweinelt commented 3 years ago

Thank you from here as well. I look forward to using idle() in home-assistant. We're currently polling every 5s and the UX is quite mediocre.