The %autoawait magic is amazing! It works very smoothly with asyncio and I've had a great time using it.
When it comes to Trio, however, the current integration is pretty limited, because Trio has a notion of structured concurrency, which means that all concurrent tasks must belong to a specific parent (called a "nursery" in Trio parlance). Therefore, if an object needs to run any tasks (e.g. a connection object that needs a background task to read incoming network data), that object's lifetime is bound to a nursery, and a nursery's lifetime is bound to the block of a context manager. The effect is that any object that needs to spawn a long-lived Trio task can only be used within a single cell.
Here's an example:

If I execute the second cell here, it will hang for a long time. Even though the connect_websocket_url() returns relatively quickly, the async with block will stay open as long as the connection's background task is running, i.e. as long as the connection itself is open.
On the prototype async REPL issue, @njsmith mentioned the following:
But we need to eventually reach a point of keeping the same loop alive over multiple cells, if we want this to be really useful.
I couldn't find any open issues tracking this idea to keep an event loop open between cells, so I'm opening this issue. I'm not sure how this would work in general, but for Trio specifically we probably want to call trio.run() once, run each cell as a task on this single Trio loop, and expose a global nursery object for launching background tasks that keep executing even when a cell isn't currently running.
I can contribute some time to helping out with this. I poked around some of the PRs and source code, but I'm not very familiar with IPython's internals, so I figure the best place to start is to brainstorm with those of you who understand the issues better than me.
The
%autoawaitmagic is amazing! It works very smoothly with asyncio and I've had a great time using it.When it comes to Trio, however, the current integration is pretty limited, because Trio has a notion of structured concurrency, which means that all concurrent tasks must belong to a specific parent (called a "nursery" in Trio parlance). Therefore, if an object needs to run any tasks (e.g. a connection object that needs a background task to read incoming network data), that object's lifetime is bound to a nursery, and a nursery's lifetime is bound to the block of a context manager. The effect is that any object that needs to spawn a long-lived Trio task can only be used within a single cell.
Here's an example:
If I execute the second cell here, it will hang for a long time. Even though the
connect_websocket_url()returns relatively quickly, theasync withblock will stay open as long as the connection's background task is running, i.e. as long as the connection itself is open.On the prototype async REPL issue, @njsmith mentioned the following:
I couldn't find any open issues tracking this idea to keep an event loop open between cells, so I'm opening this issue. I'm not sure how this would work in general, but for Trio specifically we probably want to call
trio.run()once, run each cell as a task on this single Trio loop, and expose a global nursery object for launching background tasks that keep executing even when a cell isn't currently running.I can contribute some time to helping out with this. I poked around some of the PRs and source code, but I'm not very familiar with IPython's internals, so I figure the best place to start is to brainstorm with those of you who understand the issues better than me.