Do not use asyncio in weakref.finalize#562
Conversation
because the ThreadPoolExecutor of asyncio streams complains:
Traceback (most recent call last):
File "/usr/lib/python3.12/weakref.py", line 666, in _exitfunc
f()
File "/usr/lib/python3.12/weakref.py", line 590, in __call__
return info.func(*info.args, **(info.kwargs or {}))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/tomas/.local/lib/python3.12/site-packages/concert/devices/cameras/uca.py", line 306, in _ucad_unregister_all
asyncio.run(_ucad_communicate(struct.pack("I", 14), host, port))
File "/usr/lib/python3.12/asyncio/runners.py", line 194, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/base_events.py", line 687, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "/home/tomas/.local/lib/python3.12/site-packages/concert/devices/cameras/uca.py", line 295, in _ucad_communicate
reader, writer = await asyncio.open_connection(host, port)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/streams.py", line 48, in open_connection
transport, _ = await loop.create_connection(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/base_events.py", line 1080, in create_connection
infos = await self._ensure_resolved(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/base_events.py", line 1456, in _ensure_resolved
return await loop.getaddrinfo(host, port, family=family, type=type,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/base_events.py", line 901, in getaddrinfo
return await self.run_in_executor(
^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/asyncio/base_events.py", line 863, in run_in_executor
executor.submit(func, *args), loop=self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/concurrent/futures/thread.py", line 172, in submit
raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdown
|
If you guys agree I would roll this out ASAP, it causes a page-long error on concert exit. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #562 +/- ##
=======================================
Coverage 83.52% 83.52%
=======================================
Files 133 133
Lines 10718 10718
=======================================
Hits 8952 8952
Misses 1766 1766 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@MarcusZuber the "alternative" solution would enable async destructors, not per se, but by registering some cleanup actions in concert. |
MarcusZuber
left a comment
There was a problem hiding this comment.
This fixes it here and we could merge it.
Having the possibility to use "proper" destructors would also be nice to have.
|
I am a little bit afraid when it comes to the ipython magic but it avoids duplicating async code with a sync version. So I will implement that and in the worst case we change it later. |
because the ThreadPoolExecutor of asyncio streams complains about submitting things after interpreter shutdown. Instead of trying to be super-clever, I just use the standard sockets, which work and there is no magic. @MarcusZuber this is one of the reasons why async destructors would bite us in our asses in the future.
Alternative solution (which would enable custom concert shutdown hook)
Rough code:
Actual simple concert implementation is in this commit.