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

fix: add ConnectionError to default retry #445

Merged
merged 8 commits into from May 20, 2021
1 change: 1 addition & 0 deletions google/cloud/storage/retry.py
Expand Up @@ -22,6 +22,7 @@


_RETRYABLE_TYPES = (
ConnectionError,
Copy link
Contributor

Choose a reason for hiding this comment

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

ConnectionError has a bunch of subclasses: https://docs.python.org/3/library/exceptions.html#ConnectionError . Just wanted to confirm that we consider all of these retryable?

Also, is there a test where we should add this as a test case?

Copy link
Contributor

@tseaver tseaver May 18, 2021

Choose a reason for hiding this comment

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

One or more tests should be added to the Test_should_retry class in tests/unit/test_retry.py (see the BigQuery PR for examples).

Also, that PR makes requests.exceptions.ConnectionError an explicit retryable type. The requests version does not derive from the stdlib type:

$ .nox/unit-3-9/bin/python
Python 3.9.0 (default, Apr 20 2021, 11:50:03) 
[GCC 9.3.0] on linux
>>> import requests.exceptions
>>> requests.exceptions.ConnectionError
<class 'requests.exceptions.ConnectionError'>
>>> requests.exceptions.ConnectionError.__mro__
(<class 'requests.exceptions.ConnectionError'>, <class 'requests.exceptions.RequestException'>, <class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>)

Copy link
Contributor

Choose a reason for hiding this comment

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

Note that ConnectionError is not a stdlib type in Python 2.7:

$ .nox/unit-2-7/bin/python
Python 2.7.17 (default, Apr 20 2021, 14:27:04) 
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> ConnectionError
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'ConnectionError' is not defined

We need to do something like:

try:
    _RETRYABLE_STDLIB_TYPES = {ConnectionError,)
except NameError:
    _RETRYABLE_STDLIB_TYPES = {}

and then, below:

RETRYABLE_TYPES = _RETRYABLE_STDLIB_TYPES + (
    api_exceptions.TooManyRequests,  # 429
    ...
)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tritone @tseaver Thanks for reviewing! Looking at the python3 docs and previous discussion in the Big Query, ConnectionError and its subclasses are retryable. From users feedback, this error occurs when there are multiple Cloud Functions running and/or subsequent reinvocation of Cloud Functions. The retry test is set up with a loop that tests each default retry. I'll double check to make the changes and add one or more specific tests. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tseaver I noticed that ConnectionError is not a stdlib type in Python 2.7 upon submission. Changed PR to draft to implement changes. This is exactly what I need. Thanks so much for the pointers!

api_exceptions.TooManyRequests, # 429
api_exceptions.InternalServerError, # 500
api_exceptions.BadGateway, # 502
Expand Down