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

aiohttp.Timeout raises an RuntimeError inside asyncio based tornado app. #877

Closed
imjustfly opened this issue May 16, 2016 · 8 comments
Closed
Labels
invalid This doesn't seem right outdated sprint

Comments

@imjustfly
Copy link

imjustfly commented May 16, 2016

I use aiohttp as a client inside tornado,but the aiohttp.Timeout raises an RuntimeError.

code example:

import asyncio

import aiohttp

import tornado.web
from tornado.platform.asyncio import AsyncIOMainLoop

class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        with aiohttp.Timeout(1):
            result = await aiohttp.get("www.github.com")
        self.write(result)

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    AsyncIOMainLoop().install()
    app = make_app()
    app.listen(8888)
    asyncio.get_event_loop().run_forever()

the exception is:

Uncaught exception GET / (::1)
HTTPServerRequest(protocol='http', host='localhost:8888', method='GET', uri='/', version='HTTP/1.1', remote_ip='::1', headers={'Host': 'localhost:8888', 'Connection': 'keep-alive', 'If-None-Match': '"e02aa1b106d5c7c6a98def2b13005d5b84fd8dc8"', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36', 'Accept-Language': 'en,zh-CN;q=0.8,zh;q=0.6,ja;q=0.4,zh-TW;q=0.2', 'Upgrade-Insecure-Requests': '1', 'Accept-Encoding': 'gzip, deflate, sdch'})
Traceback (most recent call last):
  File "/Users/justfly/Developer/envs/new_tornado_env/lib/python3.5/site-packages/tornado/web.py", line 1445, in _execute
    result = yield result
  File "/Users/justfly/Developer/envs/new_tornado_env/lib/python3.5/site-packages/tornado/gen.py", line 1008, in run
    value = future.result()
  File "/Users/justfly/Developer/envs/new_tornado_env/lib/python3.5/site-packages/tornado/concurrent.py", line 232, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
  File "/Users/justfly/Developer/envs/new_tornado_env/lib/python3.5/site-packages/tornado/gen.py", line 282, in wrapper
    yielded = next(result)
  File "<string>", line 6, in _wrap_awaitable
  File "test.py", line 11, in get
    with aiohttp.Timeout(1):
  File "/Users/justfly/Developer/envs/new_tornado_env/lib/python3.5/site-packages/aiohttp/helpers.py", line 478, in __enter__
    raise RuntimeError('Timeout context manager should be used '
RuntimeError: Timeout context manager should be used inside a task
@sseg
Copy link
Contributor

sseg commented Jun 2, 2016

I'll start looking into this one

@asvetlov asvetlov added the sprint label Jun 2, 2016
@sseg
Copy link
Contributor

sseg commented Jun 2, 2016

@asvetlov tornado doesn't update asyncio.tasks.Task._current_tasks so this context manager likely can't be made to work in tornado.

@asvetlov asvetlov added the invalid This doesn't seem right label Jun 2, 2016
@asvetlov
Copy link
Member

asvetlov commented Jun 2, 2016

Yes, aiohttp.Timeout work only inside an asyncio task context.
aiohttp creates a task for handling web requests by server api.
Tornado uses another technique not relying on tasks.

@asvetlov asvetlov closed this as completed Jun 2, 2016
@asvetlov
Copy link
Member

asvetlov commented Jun 5, 2016

@bdarnell I believe the issue cannot be solved but want to let you know about it's existance at least.

aiohttp.Timeout has the same implementation as asyncio.timeout but exists here because aiohttp has much shorter release cycle.

@bdarnell
Copy link

bdarnell commented Jun 5, 2016

Ugh. Yeah, that's relying on asyncio implementation details and cannot be used in any application or library that hopes to be portable across coroutine runners.

@bdarnell
Copy link

bdarnell commented Jun 5, 2016

To address @imjustfly's issue: Many asyncio methods assume that the whole world is asyncio, and don't work well when mixing asyncio and Tornado. The Tornado versions of these methods are generally better about this, so I'd recommend using tornado.gen.with_timeout instead:

from datetime import timedelta
from tornado.gen import with_timeout, convert_yielded

result = await with_timeout(timedelta(seconds=1),
    convert_yielded(aiohttp.get('http://www.example.com')))

(The convert_yielded call is because Tornado isn't perfect about accepting asyncio coroutines either. This will go away in the next release of Tornado).

@imjustfly
Copy link
Author

@bdarnell Got it ! Thank you.

@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
invalid This doesn't seem right outdated sprint
Projects
None yet
Development

No branches or pull requests

4 participants