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 and retry fixes #44

Closed
wants to merge 23 commits into from
Closed

Conversation

thehesiod
Copy link
Collaborator

Timeouts

  • this value is now automatically set so should no longer by set manually

Retries

  • previously any retry would halt ALL aio calls on the active thread (this was a bad bug)

Misc

  • simplify ClientResponseProxy
  • bugfix in aenter (should return self not aenter of ClientResponse
  • fix del to call release/close appropriately
  • fix aenter/aexits
  • add client aenter/aexit
  • fix retries of aiohttp exceptions

@thehesiod thehesiod changed the title Timeout fix Timeout and retry fixes Apr 4, 2016
@thehesiod
Copy link
Collaborator Author

btw, I'm not sure the retrylogic is completely correct. in botocore.retryhandler it uses an EXCEPTION_MAP which currently has urllib3 exceptions in them: ConnectionError, ClosedPoolError. I think this whole sections needs to be reviewed to make sure the aiohttp exceptions will be handled correctly.

@jettify
Copy link
Member

jettify commented Apr 4, 2016

Could you point me where is time.sleep logic? From quick look I do not see it...

@jettify
Copy link
Member

jettify commented Apr 4, 2016

Sorry found.

@thehesiod
Copy link
Collaborator Author

I found it while I was trying to see if I could use the botocore retry logic for aio-s3 :) Found this gem too: aws/aws-cli#1092 we can't programmatically specify the retry count :(

@jettify
Copy link
Member

jettify commented Apr 4, 2016

Changes looks good, I will execute test suite and mere this PR tomorrow.

This types of bugs is very nasty and hard to find, I should have enabled logging for slow callbacks in event loop: https://docs.python.org/3/library/asyncio-dev.html#debug-mode-of-asyncio long time ago.

@thehesiod
Copy link
Collaborator Author

cool, what do you think about the issues with the aiohttp exception types? Seems like it will require some research.

@jettify
Copy link
Member

jettify commented Apr 4, 2016

I think that logic should be not that bad : https://github.com/boto/botocore/blob/90382a41c5a23e27eda1c8fbf23fc1a3b17804ed/botocore/endpoint.py#L175-L204

here botocore does not do any exception magic, just tires to create better exceptions in two cases, so aiohttp exception bubbles up.

@jettify
Copy link
Member

jettify commented Apr 4, 2016

It could be improved but issue is not the end of the world at least :)

@thehesiod
Copy link
Collaborator Author

the issue is that it may not retry aiohttp connection exceptions as expected, see https://github.com/boto/botocore/blob/90382a41c5a23e27eda1c8fbf23fc1a3b17804ed/botocore/retryhandler.py#L147

@jettify jettify mentioned this pull request Apr 4, 2016
@jettify
Copy link
Member

jettify commented Apr 4, 2016

Oh, I see, that should be investigated, I have created issue #47 in order not to forget.

- remove __del__, we should be calling release but there doesn't seem
to be an async version of "del"
- simplify ClientResponseProxy
- bugfix in aenter
- add comments
@thehesiod
Copy link
Collaborator Author

btw, added some more clean-up and a couple bugfixes. No more unclosed sessions, yay

@thehesiod
Copy link
Collaborator Author

just submitted fix for #47

@jettify
Copy link
Member

jettify commented Apr 7, 2016

Sorry for delay, I manually merged part of commits from this PR to master. Lets do retry logic in separate PR. I will outline some issue here.

self.close()
# callers may not read the Body resulting in an unclosed ClientResponse
if self._loop.is_running():
asyncio.ensure_future(self.__response.release(), loop=self._loop)
Copy link
Member

Choose a reason for hiding this comment

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

If body is not fetched, connection and response should be closed with warning like aiohttp does, you can use:
(self.__response.close() without ensure_future. ensure_future is dangerous here because we can loose exception.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

from what I understand release is better than close as close can close the connector. And close is a coroutine so you need to run it with an ensure_future. Perhaps then just remove the del? that way you get the warning

Copy link
Member

Choose a reason for hiding this comment

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

So socket connection is not useful if all data from buffer has not been fetched, release() tries to read all available data in order to save connection and return it to connection pool (session). But since this object is garbage collected anyway, we should drop connection and warn user that he should release/close connection explicitly.

Copy link
Member

Choose a reason for hiding this comment

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

here could be corner case for instance, user decided not to fetch huge file (1GB), and ensure_future with release will try to read all the data on backgound.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

actually ya that's a better example, also I found an issue with the new properties as it seems someone is trying to set them, working on fix

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

removed del and added comment about behavior

@@ -183,6 +186,17 @@ def get_paginator(self, operation_name):
self._cache['page_config'][actual_operation_name])
return paginator

if PY_35:
@asyncio.coroutine
def __aenter__(self):
Copy link
Member

Choose a reason for hiding this comment

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

just curious why we need this? Looks like it is not public api

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this is so you can do:

session = aiobotocore.get_session()
async with session.create_client() as client:
    # do work

this way the TCPConnector is closed when you're done using the client and you don't need to manually call client.close()

Copy link
Member

Choose a reason for hiding this comment

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

Look good! we need some tests for that in separate file, because this is only python3.5 ((

@thehesiod
Copy link
Collaborator Author

closing and opening new PR per comments

@thehesiod thehesiod closed this Apr 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants