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

unexpected concurrency issue with set_volume and CastStatusListener #1003

Open
surlyhacker opened this issue Jan 8, 2025 · 2 comments
Open

Comments

@surlyhacker
Copy link

surlyhacker commented Jan 8, 2025

I have some code that deals with multiple Chromecasts and involves using CastStatusListener to listen to new_cast_status events, while also sometimes invoking set_volume on multiple Chromecasts.

I was previously running an ancient version of pychromecast and this worked fine.
Upon upgrading to 14.0.5 (with Python 3.12.3 on linux) , I noticed the following unexpected concurrency issue:

If the code within the CastStatusListener.new_cast_status event handler is taking some time to run, and before that method returns, other code within another thread tries to call set_volume, that call will block for the default 10s timeout and then always throws this error:

"Execution of set volume timed out after 10.0 s."

But by observing my Chromecasts, I can see that the volume change has in fact taken place.

I am using threading.Lock to act as a mutex and thus it is easy to reproduce this because I can force the new_cast_status to wait on that mutex and thus have a relatively long invocation time. I can reproduce this issue without explicitly creating any Threads just in the currency that naturally exists between the main python code thread and code running those event handlers.

I don't know if this is an intentional design choice or known limitation, but it is definitely something that has not always worked this way and it is unintuitive and appears to be undocumented.

@surlyhacker
Copy link
Author

surlyhacker commented Jan 8, 2025

My workaround is to simply take all of the code in new_cast_status and put it in another method that is called asynchronously so that new_cast_status returns immediately. (after creating a threading.Timer to run the actual code). That works fine but doesn't seem like it should be necessary. (and wasn't necessary in earlier versions)

@surlyhacker
Copy link
Author

Here is an example that triggers the scenario
test.txt

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

1 participant