<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, Jun 5, 2016 at 1:02 PM, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">So in the case of that Tornado example, who does the sleeping (or how<br>
is the exception scheduled)? </blockquote><div><br></div><div>The exception is scheduled with IOLoop.add_timeout (equivalent to asyncio's call_later). One difference between the two is that Tornado's with_timeout creates a new future (and a new coroutine runner) instead of cancelling the input future. </div><div><br></div><div>The code is here: <a href="https://github.com/tornadoweb/tornado/blob/11bd951cc04747c0f03c71575d004f322950a5c3/tornado/gen.py#L835">https://github.com/tornadoweb/tornado/blob/11bd951cc04747c0f03c71575d004f322950a5c3/tornado/gen.py#L835</a></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">We may not be able to retract this from<br>
3.5.2 (RC1 goes out next weekend) but asyncio is still provisional<br>
until the 3.6 feature freeze in September. What's a better design?<br></blockquote><div><br></div><div>I prefer a function that wraps an awaitable (as in Tornado's implementation), but this does have a performance impact. If we want to avoid that, then I think an `async with` context manager would be a better choice than an ordinary context manager, but I'd like to have a proof of concept implementation that works across asyncio and at least one other platform before committing to that design.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
(FWIW asyncio.timeout() takes an optional loop parameter, but that's<br>
probably not helpful.)<br></blockquote><div><br></div><div>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)</div><div><br></div><div>-Ben</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
On Sun, Jun 5, 2016 at 8:56 AM, Ben Darnell <<a href="mailto:ben@bendarnell.com">ben@bendarnell.com</a>> wrote:<br>
> It has come to my attention (<a href="https://github.com/KeepSafe/aiohttp/issues/877" rel="noreferrer" target="_blank">https://github.com/KeepSafe/aiohttp/issues/877</a>)<br>
> that Python 3.5.2 (!) introduced a new context manager asyncio.timeout,<br>
> which attaches a timeout to the current asyncio.Task. Any library or<br>
> application that uses this feature will not be portable to other coroutine<br>
> runners.<br>
><br>
>     with asyncio.timeout(1):<br>
>         result = await aiohttp.get('<a href="http://www.example.com" rel="noreferrer" target="_blank">http://www.example.com</a>')<br>
><br>
> It's difficult to make this interface portable. We'd need to introduce a<br>
> global thread-specific object that all of the coroutine runners could<br>
> register the current task on, and define an interface that asyncio.timeout<br>
> would call on that object to set the timeout. We could get rid of the global<br>
> if the context manager used `async with` instead of `with`, since that would<br>
> give us a way to communicate with the coroutine runner directly, but the net<br>
> result is still that each runner needs to implement hooks for this feature<br>
> (the hooks may or may not be generalizable to other features in the future).<br>
><br>
> If our goal is portability across coroutine runners, then asyncio.timeout()<br>
> needs to go back to the drawing board. If the goal is to extend asyncio.Task<br>
> to be the one true coroutine runner then we could leave it as-is.<br>
><br>
> For comparison, Tornado's equivalent to asyncio.timeout is<br>
> tornado.gen.with_timeout(), and it has no special interactions with the<br>
> coroutine runner:<br>
><br>
>     result = await with_timeout(timedelta(seconds=1),<br>
>                      convert_yielded(aiohttp.get("<a href="http://www.example.com" rel="noreferrer" target="_blank">http://www.example.com</a>")))<br>
><br>
> (The convert_yielded call won't be needed in the next release of Tornado.<br>
> The use of timedelta is because Tornado prefers absolute deadlines instead<br>
> of relative timeouts, so that's how plain numbers are interpreted).<br>
><br>
> -Ben<br>
><br>
</div></div>> _______________________________________________<br>
> Async-sig mailing list<br>
> <a href="mailto:Async-sig@python.org">Async-sig@python.org</a><br>
> <a href="https://mail.python.org/mailman/listinfo/async-sig" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/async-sig</a><br>
> Code of Conduct: <a href="https://www.python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">https://www.python.org/psf/codeofconduct/</a><br>
<span class=""><font color="#888888"><br>
<br>
<br>
--<br>
--Guido van Rossum (<a href="http://python.org/~guido" rel="noreferrer" target="_blank">python.org/~guido</a>)<br>
</font></span></blockquote></div><br></div></div>