Regarding to asyncio event loop globalness. In my code I never use implicit global event loop but always pass the instance everywhere when needed. aiohttp as well as other aio-libs libraries supports optional loop=None parameter. The only reason why the loop is optional -- we are trying to follow asyncio conventions. But frankly speaking I found implicit event loop both non-obvious and error-prone. It would be nice to always pass event loop explicitly in asyncio-based code but ship has sailed years ago. On Sun, Jun 5, 2016 at 11:38 AM Nathaniel Smith <njs@pobox.com> wrote:
On Sun, Jun 5, 2016 at 10:24 AM, Ben Darnell <ben@bendarnell.com> wrote: [...]
No, it's not helpful because event loops and coroutine runners are independent. It's easy to find the current event loop (there are globals for that), but you can't really interact with the coroutine runner except via yield/await (unless we introduce new globals for this purpose)
Of course the reason it takes the loop argument is that in asyncio, event loops and coroutine runners aren't independent at all -- the loop is a global, and then the current coroutine runner is part of the loop state, so effectively the current coroutine runner is already a global:
https://docs.python.org/3/library/asyncio-task.html#asyncio.Task.current_tas...
In the curio approach they also aren't independent -- they don't have any magic globals, but for them the event loop and coroutine runner are the same object.
And AFAICT the tornado.gen.with_timeout wrapper doesn't deal with coroutines/coroutine runners at all? I just read the source, but I couldn't fully follow it. If I write async def do_stuff(): try: await aiohttp.get("https://python.org") except: print("oops, cleaning up") raise else: print("did it!") await tornado.gen.with_timeout(timedelta(seconds=0.0001), do_stuff()) and the timeout fires, then is the output "oops, cleaning up", "did it!", or nothing at all?
I guess the main case where coroutine runners are really independent from an event loop is when you have random little ad hoc coroutine runners that aren't directly integrated with an event loop at all. E.g., in my async_generator package the @async_generator decorator acts as a coroutine runner that adapts a regular coroutine into an async iterator, by intercepting special 'await yield_(...)' messages and transparently proxying other messages to the underlying coroutine runner. Before I read the source I was expecting that maybe tornado.gen.timeout_after would work in a broadly similar way, but apparently I was wrong :-).
I don't have any argument here -- just trying to think aloud to understand the design space better...
-n
-- Nathaniel J. Smith -- https://vorpus.org _______________________________________________ Async-sig mailing list Async-sig@python.org https://mail.python.org/mailman/listinfo/async-sig Code of Conduct: https://www.python.org/psf/codeofconduct/
-- Thanks, Andrew Svetlov