[Async-sig] A possible tiny step towards event loop interoperability

Yury Selivanov yselivanov at gmail.com
Sat Jun 4 00:08:09 EDT 2016


> On Jun 3, 2016, at 11:29 PM, Nathaniel Smith <njs at pobox.com> wrote:
> 
> On Fri, Jun 3, 2016 at 7:40 PM, Yury Selivanov <yselivanov at gmail.com> wrote:
>> 
>>> On Jun 3, 2016, at 8:14 PM, Ben Darnell <ben at bendarnell.com> wrote:
>>> 
>>> I think this could be useful, but's answering the question of "what coroutine runner is this", not "what event loop is this". It's already possible to stack one event loop on top of another so that the question of event loop is ambiguous, but any `async def` function or other coroutine has exactly one coroutine runner. The identity of the coroutine runner matters more in practice than the event loop (PEP 484 has standardized the event loop interface but left coroutine runners unspecified).
>> 
>> Right, let’s discuss the hypothetical ‘await what_coroutine_runner_is_this()’.  Which, in case of asyncio, would return an instance of the current Task, right?
> 
> I guess what I was really thinking of was
> 
>  await what_api_does_this_coroutine_runner_implement()
> 
> so if you really needed to you could write code that does
> asyncio-things on asyncio, curio-things on curio, etc., and the caller
> doesn't have to care.
> 
> I'll emphasize again that this is a trivial tiny suggestion :-)


Glyph and Ben want information about the coroutine runner in __await__, where awaiting on something is not possible.

If we are talking about coroutines that users of curio/twisted/tornado/asyncio will write, then I don’t think they will need that thing either — it’s too low level.

What makes interoperability between asyncio, tornado and twisted possible is that they all use similar event loops designs.  They all have something similar to call_soon and other callbacks related APIs, Future/Deferred etc.  What’s good about Futures and Deferreds is that they are well-defined objects with APIs etc.

In curio, David intentionally didn’t want to have anything similar to Futures and Deferreds.  Instead, he introduced a concept of “traps” (see [1]), which are generators wrapped with “@types.coroutine” yielding hardcoded tuples, that curio “kernel” can understand.  Which is a very neat and clever design, except that it doesn’t compose with anything else.  With that design, it’s essentially impossible for asyncio coroutines to await on curio coroutines. The only way would be to implement all of curio APIs in asyncio in a wrapper to do this:

   async def asyncio_coroutine():
        await curio_adapter(curio_coroutine())

I’m not sure if it’s possible for curio coroutines to transparently await on asyncio coroutines without a significant refactoring of curio.  But even if David decides to do that, for compatibility with Futures he’ll only need to add ‘isinstance(trap, Future)’ in his kernel code, no new APIs are needed (IMO).

[1] https://github.com/dabeaz/curio/blob/master/curio/traps.py#L25

Yury



More information about the Async-sig mailing list