[Async-sig] asyncio.timeout() is not portable

Ben Darnell ben at bendarnell.com
Sun Jun 12 12:15:38 EDT 2016


On Wed, Jun 8, 2016 at 9:38 PM, Andrew Svetlov <andrew.svetlov at gmail.com>
wrote:

> My first thought was to use `async with` but I found that just `with` also
> works.
>

> Sorry, but I don't follow how async context manager may be better.
>

`async with` communicates directly with the coroutine runner. Plain `with`
requires that the coroutine runner be discoverable in some other way (via a
global). Either way, for `asyncio.timeout` to be portable to other
coroutine runners, we must define a protocol that coroutine runners may
implement.

If we use `async with`, that protocol is something like "if the coroutine
yields an instance of asyncio.TimeoutSetter, the runner should set its
timeout accordingly".

If we use plain `with`, we would need to move asyncio.Task._current_task
somewhere public (an attribute of EventLoop? a global threading.local?) and
the protocol would be that each coroutine runner must register itself there
while it is on the top of the stack and implement a `set_timeout()` method.

I believe the `async with` solution will perform better (an isinstance()
check on every yielded object, plus one extra yielded object when the
timeout feature is used, versus at least two operations on a central
registry every time the coroutine runner enters or leaves the stack), and
it also degrades more gracefully (the TimeoutSetter object could be a
subclass of Future that resolves instantly so runners that don't understand
it can simply ignore it. A runner that doesn't participate in the
current_task registry may leave the wrong task at the top of the stack).

-Ben


>
> On Wed, Jun 8, 2016 at 10:49 AM Yury Selivanov <yselivanov at gmail.com>
> wrote:
>
>>
>> > On Jun 8, 2016, at 1:15 PM, Andrew Svetlov <andrew.svetlov at gmail.com>
>> wrote:
>> >
>> > asyncio.timeout behaves like asyncio.wait_for BTW.
>> > It cancels inner tasks and sends asyncio.TimeoutError to outer.
>>
>> Right.  And I think it’s a totally normal behaviour for asyncio.
>>
>> The only thing I’d fix in asyncio.timeout() (aside from resolving
>> Ben’s questions) is to make it use ‘async with’ statement.
>>
>> Yury
>>
>> --
> Thanks,
> Andrew Svetlov
>
> _______________________________________________
> Async-sig mailing list
> Async-sig at python.org
> https://mail.python.org/mailman/listinfo/async-sig
> Code of Conduct: https://www.python.org/psf/codeofconduct/
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/async-sig/attachments/20160612/1648d849/attachment.html>


More information about the Async-sig mailing list