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

error in name-resolving when using the library in async mode on python 3.10 #9

Closed
marc-portier opened this issue Aug 20, 2022 · 2 comments

Comments

@marc-portier
Copy link
Contributor

Not really sure things can be fixed inside this library, but by mentioning it here I hope it can warn / help people about this, or even better gather some work-around ?

I am trying to use the announce feature in asynchronous mode through:

def play_sound(api_uri, sound_uri):
    async def play_and_close(): 
        try :
            log.info(f"Now playing {sound_uri} on {api_uri}")
            sndsrv = AmpliPi(api_uri, timeout=30)
            sound: Announcement  = Announcement(media=sound_uri, vol_f=0.6, source_id=3)
            await sndsrv.announce(sound)
            await sndsrv.close()
        except Exception as e:
            log.error("playing sound failed.")
            log.exception(e)
    asyncio.run(play_and_close())

Note: I am using the asyncio.run() trick because the play_sound() will be called from some event-handling system that is not applying any await --> so the asyncio.run() is there to avoid method X never been awaited for

This works if I just use the local IP address in the api_uri to amplipi like say http://192.168.0.15/

It fails however if I use the local name http://amplipi.myhome.local/ with this elaborate stack-trace:

2022-08-20 10:32:12 @__main__                [ERROR   ] playing sound failed.
2022-08-20 10:32:12 @__main__                [ERROR   ] can't register atexit after shutdown
Traceback (most recent call last):
  File "/mnt/extra/projects/mpo/home-autom/docker-k79-nhc2/./doorbell-srv.py", line 34, in play_and_close
    await sndsrv.announce(sound)
  File "/home/mpo/.local/lib/python3.10/site-packages/pyamplipi/amplipi.py", line 122, in announce
    response = await self._client.post('announce', announcement.json())
  File "/home/mpo/.local/lib/python3.10/site-packages/pyamplipi/client.py", line 148, in post
    async with self._http_session.post(
  File "/home/mpo/.local/lib/python3.10/site-packages/aiohttp/client.py", line 1138, in __aenter__
    self._resp = await self._coro
  File "/home/mpo/.local/lib/python3.10/site-packages/aiohttp/client.py", line 535, in _request
    conn = await self._connector.connect(
  File "/home/mpo/.local/lib/python3.10/site-packages/aiohttp/connector.py", line 542, in connect
    proto = await self._create_connection(req, traces, timeout)
  File "/home/mpo/.local/lib/python3.10/site-packages/aiohttp/connector.py", line 907, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
  File "/home/mpo/.local/lib/python3.10/site-packages/aiohttp/connector.py", line 1154, in _create_direct_connection
    hosts = await asyncio.shield(host_resolved)
  File "/home/mpo/.local/lib/python3.10/site-packages/aiohttp/connector.py", line 880, in _resolve_host
    addrs = await self._resolver.resolve(host, port, family=self._family)
  File "/home/mpo/.local/lib/python3.10/site-packages/aiohttp/resolver.py", line 33, in resolve
    infos = await self._loop.getaddrinfo(
  File "/usr/lib/python3.10/asyncio/base_events.py", line 860, in getaddrinfo
    return await self.run_in_executor(
  File "/usr/lib/python3.10/asyncio/base_events.py", line 813, in run_in_executor
    executor = concurrent.futures.ThreadPoolExecutor(
  File "/usr/lib/python3.10/concurrent/futures/__init__.py", line 49, in __getattr__
    from .thread import ThreadPoolExecutor as te
  File "/usr/lib/python3.10/concurrent/futures/thread.py", line 37, in <module>
    threading._register_atexit(_python_exit)
  File "/usr/lib/python3.10/threading.py", line 1497, in _register_atexit
    raise RuntimeError("can't register atexit after shutdown")
RuntimeError: can't register atexit after shutdown

References on the web I could find all seem to indicate some internal python change since 3.9

in some weird way it doesn't seem to play well with (at least) the getaddrinfo inside aiohttp

@linknum23
Copy link
Collaborator

For now the workaround is likely just to resolve the address ahead of time, refeshing the cached resolution on failure.

Another way to handle this would be to listen to amplipi's mdns broadcasts. Check out the contents of _amplipi._tcp.local. . Thats what the HA integration uses.

@marc-portier
Copy link
Contributor Author

in fact, I just gave this 'fault-generating' code another spin with updated versions of all packages involved -- and happy to report the problem does no longer persist.
So probably somebody down somewhere has given this the proper attention?

For me it is ok to close this.

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

2 participants