Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeout context manager #611

Merged
merged 12 commits into from
Nov 25, 2015
Merged

Timeout context manager #611

merged 12 commits into from
Nov 25, 2015

Conversation

jettify
Copy link
Member

@jettify jettify commented Oct 31, 2015

@asvetlov I implemented your idea about timeout context manager.

Open questions:

  1. May be we should implement context manager as regular one with Timeout(1): instead async with Timeout(1)?:
  2. Do we need cancel logic:
async with Timeout(1) as timeout:
   timeout.cancel()
   await do() 
  1. what about raising exception in case of blocking code?:
async with Timeout(1) as timeout:
    time.sleep(2)

Edit: Add related stackoverflow question:
https://stackoverflow.com/questions/33217429/creating-a-temporary-async-timer-callback-to-a-bound-method-with-python-asyncio

@ludovic-gasc
Copy link
Contributor

interesting idea, I see this more in asyncio itself than aiohttp.

@kxepal
Copy link
Member

kxepal commented Nov 1, 2015

Nice!

  1. I think regular context manager is enough here.
  2. While I can see the cases for having this, I think better not since this will make code reading more complicated. You need to be sure, that exact block may run no longer than specified timeout.
  3. That would be expected.

However, I have bad feelings that this context manager wouldn't work correctly for the tasks that are spawned from the timeout block:

async def bar():
    await asyncio.sleep(3)
    print('hello!')

async def test():
    async with Timeout(1):
        t = asyncio.ensure_future(bar())
        await asyncio.sleep(1)
        await t
    await asyncio.sleep(3)

asyncio.get_event_loop().run_until_complete(test())

I was expected to see an exception, or Task was destroyed but it is pending!, but not "hello!".
For the case when I do await asyncio.ensure_future(bar()) it indeed doesn't makes bar to be completely executed.

@asvetlov
Copy link
Member

asvetlov commented Nov 1, 2015

Looks like we should make the same guarantees for Timeout as async_for has.

@jettify
Copy link
Member Author

jettify commented Nov 2, 2015

I ported tests from asyncio.wait_for. And added blocking feature like in wait_for:

async with Timeout(None):
    t = await future

in this case timeout is not calculated, similar to await wait_for(future, timeout=None)

@jettify
Copy link
Member Author

jettify commented Nov 7, 2015

as result of discussion in IRL:

  1. timeout=None removed
  2. cancel api removed
  3. updated tests

:param raise_error: if set, TimeoutError is raised in case of timeout
:param loop: asyncio compatible event loop
"""
def __init__(self, timeout, *, raise_error=False, loop=None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raise_error should be True by default (asyncio.wait_for() raises exception on timeout).
After thinking I doubt do we need the parameter at all.

@jettify
Copy link
Member Author

jettify commented Nov 9, 2015

raise_error argument removed

self._cancel_handler.cancel()

def _cancel_task(self):
self._cancelled = self._task.cancel()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add self._task = None

@asvetlov asvetlov merged commit 71995c1 into aio-libs:master Nov 25, 2015
@asvetlov asvetlov added this to the 0.19 milestone Nov 25, 2015
@lock
Copy link

lock bot commented Oct 29, 2019

This thread has been automatically locked since there has not been
any recent activity after it was closed. Please open a new issue for
related bugs.

If you feel like there's important points made in this discussion,
please include those exceprts into that new issue.

@lock lock bot added the outdated label Oct 29, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 29, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants