-
-
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
Peer cancellation policy documentation unclear #5814
Comments
aiohttp/aiohttp/web_protocol.py Lines 524 to 528 in 88d1f80
But I think the reason is the |
Indeed, the example provided never tries to read anything, it is cancelled in the sleep. |
You can try following code: import itertools
from aiohttp import web
async def handle(request):
response = web.StreamResponse(
status=200,
reason='OK',
headers={'Content-Type': 'text/plain'},
)
await response.prepare(request)
for line in itertools.cycle('abc'):
await response.write(line.encode('utf-8'))
await response.write_eof()
return response
app = web.Application()
app.add_routes([web.get("/", handle), web.get("/{name}", handle)])
if __name__ == "__main__":
web.run_app(app) It's a dead loop, send the Cancel the
|
Also worth noting that the OSError mentioned in the documentation would never be raised in the original example, because it does not read from the response at all, it only uses information from |
Hm, ok. This is the commit that changed the docs: b74306d#diff-af5cbca68a75093b494497c857162462f30fc2f981c4b1104c57bd6a99d8db6c Notice the new documentation doesn't say anything about cancellation. What's very likely to happen is that the peer will drop the connection when the handler is busy doing something else, like reading from a database or a different API. In that case the handler task will still be thrown a |
Hmm, interesting. I think that documentation should probably be put back in. @webknjaz Thoughts? |
I think v4.0 changes something wrt autocancelation. So compare master vs 3.8 branch. |
Looks like the same change was made to 3.7: Testing against master and 3.8, I get the same cancellation result. Looking at the tests in that commit, it seems that they all test that a ConnectionError occurs on reading, but none of the tests check what happens when If the desired behaviour is that the code continues without cancelling, then we'll need to look at stopping this cancellation. I'm not sure where the cancellation is actually coming from though, as a traceback is useless in this scenario. The code that @Hanaasagi pointed to is catching a CancelledError, not throwing it. So, I don't think it's there. |
My opinion is that the cancellation was actually a good thing, and useful. However, when upgrading aiohttp for one of my work projects I noticed the changelog entry and assumed aiohttp simply stopped cancelling (due to the documentation changes and the changelog itself), and was surprised when I realized aiohttp is still cancelling. Even if you refactor to remove cancelling tasks of disconnecting peers, please leave a switch to reenable the behavior because there's no way to get this functionality without aiohttp cooperation. On the other hand, if aiohttp continues cancelling and you want to ignore it, it's actually easy (for example, |
It's coming from here( aiohttp/aiohttp/web_protocol.py Lines 322 to 327 in 10995e8
|
Thanks. So, the question is what is the intended approach? The new documentation suggests we shouldn't be cancelling at all, although this seems less optimal. The old approach would be to cancel always. But, currently, it's a mix of OSError if you are awaiting on a read/write and cancelling if you awaiting on something else, which seems a little confusing to me. Curiously, I can't actually get the OSError to appear in simple testing. If I use e.g. If the handler in the example is changed to:
This always prints the body for me, even if the client is already disconnected. If you add |
It seems to be fixed by #6727. The server's behavior now follows what the documentation says. |
Okay, sounds like it's solved. |
Describe the bug
The docs (https://docs.aiohttp.org/en/stable/web_advanced.html#peer-disconnection) clearly state:
As far as I understand, this behavior replaces the old behavior, which was to cancel the task running the handler as soon as a peer disconnected.
But if you curl what I've pasted in the To Reproduce section and kill curl after 1 second, the request handler will actually be cancelled, which is the old behavior. So which is correct?
To Reproduce
Expected behavior
Not sure.
Logs/tracebacks
Python Version
aiohttp Version
multidict Version
yarl Version
OS
Ubuntu Linux
Related component
Server
Additional context
No response
Code of Conduct
The text was updated successfully, but these errors were encountered: