Use consistent terminology to distinguish functions that run sync callables vs. async callables #68
We have a bunch of functions that take a callable and run it:
The first and last take an async function, and the middle two take a sync function. Our terminology here is really confusing. And unfortunately the obvious solution of renaming it to
Brainstorming some options (format: run-an-async-fn / run-a-sync-fn / call soon):
The text was updated successfully, but these errors were encountered:
I'm leaning towards
in_trio = trio.current_blocking_reentry_vehicle() # then in your thread in_trio.run(...)
And you can imagine providing similar vehicles to reenter from asyncio or twisted or whatever.
...for asyncio / twisted / etc., it also makes sense to have trio→them reentry vehicles. Might want to keep that in mind when naming things: an asyncio→trio vehicle is no the same as a trio→asyncio vehicle.
(If an API design allows for an awesomely punny name then it's probably a good idea. I'm pretty sure that's in the zen of python somewhere.)
Part of the changes for python-triogh-68 Also keeps run_in_worker_thread around as a deprecated alias.
We could call them "portals" maybe, retreating from the grim science fictional present into a pastoral fantasy past. Or, you know, Aperture Science
When we get to implementing these interop mechanisms with other event loops (e.g. this already came up with kivy in #267) then there are two natural approaches. We could have one object that acts as a portal from trio→asyncio and a second object that acts as a portal from asyncio→trio, so something like
The subtlety here is that internally, a bidirectional portal probably wants to capture a trio run and an asyncio loop, and use them in both directions. OTOH a unidirectional portal can use the ambient loop on the sending side, and only has to capture some representation for the receiving side. In principle this makes the unidirectional version a little more elegant, and it's more generic in some sense. But I'm dubious that this is enough to make up for the extra conceptual cost of having two objects to initialize and keep track of.
The only way to capture a trio loop is by running something in trio. This could end up being a bit awkward if any other libraries have the same constraint, b/c then how do you create a bidirectional loop? OTOH I don't think any other libraries have the same constraint. (And it wouldn't be hard to work around in trio either; really it's just that it would want to call
I guess a kind of elegant design would be to have a generic
We don't actually have to decide any of this now. I'm just trying to think it through a bit because maybe it effects what we want to call the methods for entering trio from a generic blocking thread. This is inherently unidirectional because you can't assign work to a random generic thread that doesn't have an event loop running in it, but maybe for consistency the names should still be
Also wondering if we should replace
class AsyncioTrioPortal def __init__(self, asyncio_loop, trio_run_token=None): ...
if we can say "for
class AsyncioTrioPortal def __init__(self, asyncio_loop, trio_call_soon_thread_and_signal_safe=None): ...
where it's just... harder to explain what that thing is.
Another use for a
It could potentially provide some other niceties too, like a way to check if the loop is running without entering it. Though... meh, this is racey, not sure it's really interesting. You can always