-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Client request timeout should be optional #1180
Comments
Tornado's couroutine runner is quite not compatible with asyncio, you know. Unfortunately Tornado doesn't follow the rule (BTW it doesn't support own coroutine runner cancelling as well). As workaround I'm suggesting the following decorator:
See also #1176 P.S. P.P.S |
@asvetlov Thanks for the quick response! I'm not suggesting things change at the level of the |
If the proposed decorator works for you -- we might add a hint to documentation. |
@asvetlov Right, I understand. But that is much more complicated than what I'm suggesting here. Inside of if timeout is None:
conn = yield from self._connector.connect(req)
else:
with Timeout(timeout, loop=self._loop):
conn = yield from self._connector.connect(req) (with similar changes applied in the other places No decorators required, and no mucking around in the depths of Tornado. This way people can use @bdarnell with |
I'd really appreciate it if the new rules made it into the PEP first, and then What exactly is the proposed modification to PEP 3156 and where is this being discussed? It sounds like it's going to be a backwards-incompatible change for Tornado to become compliant with the proposed new rules; changes like this should probably be hammered out on async-sig so that people like Glyph and I can participate and minimize the disruptions. I think there's a path forward in which Tornado moves to using |
@bdarnell a PR for PEP 3156 updating is not exists yet but I want to publish it soon. UPD: task cancellation is the part of the standard: https://www.python.org/dev/peps/pep-3156/#tasks Don't get me wrong: I'd love to see Tornado compatible with I've looked into Tornado's support for coroutines and found that the problem cannot be solved by couple lines patch, it's true. Please, correct me if I'm wrong but right now Tornado's coroutine runner doesn't support task cancellation, this is the main problem. Accessing to asyncio event loop has a AbstractEventLoop.create_task() method and even AbstractEventLoop.set_task_factory (both are not mentioned by PEP but reflected in asyncio docs again). Theoretically Tornado may reimplement the Your patch makes sense also. Anyway, That's it. |
Interesting. Sounds like there's been a lot of public APIs added to the stdlib
But this is the most important part:
Without some assurance that, if I make this change and get it working, you won't unilaterally break it again with no notice in the future, I don't know if I should bother. Instead maybe my time would be better served by figuring out how to distinguish Tornado native coroutines from |
Making Tornado's coroutine runner a superset of asyncio's sounds a great idea. I have no striving to break Tornado's compatibility for freak, sure. P.S. |
On Sun, Sep 18, 2016 at 7:00 AM, Ben Darnell notifications@github.com wrote:
Sorry about that. We've been using a variety of venues for these discussions, e.g. the asyncio tracker, python-ideas, python-dev, the bugs.python.org tracker. We also fell behind on updating the PEP -- I actually want it updated, and the API frozen for Python 3.6, and the PEP no longer provisional, so that future API changes will have to be backwards compatible. So now's a good time to hammer out the remaining issues. Possibly the actual code is more amenable to reuse by Tornado than the PEP, in which case we should just make sure that the PEP describes that behavior in sufficient detail. It's also possible that changes to the actual code need to be made, in which case we're slightly more in a hurry (the Python 3.6 release schedule moves inexorably forward, see PEP 494. |
FYI: I've created PR #1524 to be able to achieve separate read + connection timeouts discussed in the fifth comment by @adamrothman |
closing as it is possible to pass |
@fafhrd91 I'm not sure the recent changes address the original issue, which was to be able to pass |
if you pass |
here is code for None timeout https://github.com/KeepSafe/aiohttp/blob/master/aiohttp/helpers.py#L722 |
Sorry! I misunderstood. Thanks @fafhrd91 and @thehesiod. |
wow, just realized gvanrossum commented in this thread, impressive :) |
@bdarnell this server works just fine on Tornado 4.4.2 with #!/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', timeout=None) 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() |
@adamrothman technically you can create custom |
This is the decorator I ended using based on @asvetlov's answer (there was a missing import functools
def deco(func):
@functools.wraps(func)
async def wrapper(*args, **kwargs):
return await asyncio.get_event_loop().create_task(func(*args, **kwargs))
return wrapper
class Handler(tornado.web.RequestHandler):
@deco
async def get(self):
... |
this situation with |
What change would you propose for |
I think I will work on bug report. |
I've spent about 2 hours finding problem and right solution. Thank you @adamrothman @asvetlov and @jcugat - It would be great to see these snippets in docs. |
@jcugat last time I knew |
But it returns a Future, which can be awaited.
…On Jul 24, 2017 8:30 PM, "AraHaan" ***@***.***> wrote:
@jcugat <https://github.com/jcugat> last time I knew
AbstractEventLoob.create_task was an normal syncrous function, not an
asyncronous one.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#1180 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACwrMlgubQXLrx4v9N401V4h3Q6y7vS1ks5sRWFggaJpZM4J_R3i>
.
|
Long story short
As described in #877, attempting to use
aiohttp.Timeout
in a Tornado-based app results in aRuntimeError
. 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 useaiohttp.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 aTimeout
. This seems a bit heavy-handed as it makes it impossible to useaiohttp
's client with Tornado, even with Ben's suggested workaround. If thetimeout
kwarg toaiohttp.ClientSession::request
isNone
, 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):And the resulting error:
Environment
aiohttp
1.0.0tornado
4.4.1Thoughts
aiohttp
relies on @asvetlov'sasync_timeout
library internally to handle timeouts.async_timeout
is incompatible with coroutine runners that are notasyncio
, as it relies on callingasyncio.Task.current_task
. Perhaps it would be possible to makeasync_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.The text was updated successfully, but these errors were encountered: