Skip to content

Client request timeout should be optional #1180

Closed
@adamrothman

Description

Long story short

As described in #877, attempting to use aiohttp.Timeout in a Tornado-based app results in a RuntimeError. In that issue, @bdarnell offers a solution that uses Tornado's own timeout utility. Through version 0.22.5, aiohttp's client request plumbing does not use aiohttp.Timeout internally; users were expected to apply it externally when desired.

The 1.0.0 release of aiohttp includes dc79e14, which forces all requests to use a Timeout. This seems a bit heavy-handed as it makes it impossible to use aiohttp's client with Tornado, even with Ben's suggested workaround. If the timeout kwarg to aiohttp.ClientSession::request is None, it should work the way it used to.

Steps to reproduce

The following test server can be used to consistently reproduce a RuntimeError as in #877 (trace follows):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from asyncio import get_event_loop

from aiohttp import ClientSession
from tornado.httpserver import HTTPServer
from tornado.platform.asyncio import AsyncIOMainLoop
from tornado.web import Application
from tornado.web import RequestHandler


class Handler(RequestHandler):

    async def get(self):
        async with ClientSession() as client:
            async with client.get('https://www.google.com') as response:
                self.write(await response.text())


if __name__ == '__main__':
    AsyncIOMainLoop().install()

    app = Application([
        (r'/', Handler),
    ])
    server = HTTPServer(app)
    server.listen(9999)

    get_event_loop().run_forever()

And the resulting error:

Uncaught exception GET / (127.0.0.1)
HTTPServerRequest(protocol='http', host='localhost:1337', method='GET', uri='/', version='HTTP/1.1', remote_ip='127.0.0.1', headers={'Host': 'localhost:1337', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'keep-alive', 'User-Agent': 'HTTPie/0.9.6', 'Accept': '*/*'})
Traceback (most recent call last):
  File "/Users/adam/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tornado/web.py", line 1469, in _execute
    result = yield result
  File "/Users/adam/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tornado/gen.py", line 1015, in run
    value = future.result()
  File "/Users/adam/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tornado/concurrent.py", line 237, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
  File "/Users/adam/.pyenv/versions/3.5.2/lib/python3.5/site-packages/tornado/gen.py", line 285, in wrapper
    yielded = next(result)
  File "<string>", line 6, in _wrap_awaitable
  File "./test.py", line 16, in get
    async with client.get('https://www.google.com') as response:
  File "/Users/adam/.pyenv/versions/3.5.2/lib/python3.5/site-packages/aiohttp/client.py", line 565, in __aenter__
    self._resp = yield from self._coro
  File "/Users/adam/.pyenv/versions/3.5.2/lib/python3.5/site-packages/aiohttp/client.py", line 197, in _request
    with Timeout(timeout, loop=self._loop):
  File "/Users/adam/.pyenv/versions/3.5.2/lib/python3.5/site-packages/async_timeout/__init__.py", line 33, in __enter__
    raise RuntimeError('Timeout context manager should be used '
RuntimeError: Timeout context manager should be used inside a task
500 GET / (127.0.0.1) 3.57ms

Environment

  • macOS 10.11.6
  • Python 3.5.2
  • aiohttp 1.0.0
  • tornado 4.4.1

Thoughts

aiohttp relies on @asvetlov's async_timeout library internally to handle timeouts. async_timeout is incompatible with coroutine runners that are not asyncio, as it relies on calling asyncio.Task.current_task. Perhaps it would be possible to make async_timeout compatible with other runners? Or maybe it's not possible. That's out of the scope of what I'm proposing here. I see the value of making it possible to manage the timeout internally, but it would be nice if there was a way to disable this behavior when desired.

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions