trio
trio copied to clipboard
trio's guest mode breaks sniffio.current_async_library in certain cases
I am opening this bug as requested on Gitter (see link below).
Summary
When running trio as a guest (in a tkinter
event loop in this case), and using trio.Nursery::start_soon()
from the host event loop to schedule work to be done in the trio event loop, sniffio.current_async_library()
doesn't detect the trio loop and raises.
Details
When running trio in guest mode in the tkinter
event loop, the docs advise to have both loop have the same lifetime. This is achieved by passing a done_callback
to trio.start_guest_run()
that terminates the host loop. The closing mechanism is then to terminate the trio loop (most likely by cancelling it), which in turn terminates the host loop.
The doc does not provide examples on how to start async function inside the trio loop from the host loop. When reading it, it was unclear to me what functions or methods are safe to call from outside the trio loop. I considered trio.Nursery::start_soon
, trio.SendChannel::put_nowait()
, trio.lowlevel.TrioToken::run_sync_soon()
and trio.lowlevel.spawn_system_task()
.
As nurseries seemed like an excellent control flow mechanism and a central concept in trio, I tried the Nursery. A Nursery is created in the trio loop, immediately calls nursery.start_soon(trio.sleep_forever)
to remain available, and the host loop gets a reference to this nursery to schedule async function in it.
This works for trio code, but seem to breaks sniffio.current_async_library()
, which raises an exception. I my particular use-case, sniffio
was used under the hood by asks
, which was used for http requests.
I wrote a (relatively) small example code to showcase the issue, as well as the fix proposed on Gitter. See the link below.
I am unsure if this is an actual bug in sniffio, or trio guest mode, or bad code on my part.
Maybe the doc of trio.lowlevel.start_guest_run()
could be improved to show how to do this correctly (e.g. using memory channels), so as to avoid future confusion or unsafe code.
Additional resources
- discussion on gitter https://gitter.im/python-trio/general?at=619f8ac5c6149e53494c05b7
- reproducing code: https://gist.github.com/QuentinSoubeyran/138f0784f9d596f5727ca2bea830ffcd
Versions:
- OS: Ubuntu 20.04
- python 3.10
- trio 0.19.0
- sniffio 1.2.0
If any info is missing, I'll gladly improve this issue !
Words of thank
Thank you all for the trio lib, it looks awesome ! I was extremely glade to find about guest mode, it really feels like the correct way to use async I/O and a UI together.