Skip to content

Commit

Permalink
Added backoff support for route53 throttling.
Browse files Browse the repository at this point in the history
Instead of erroring out on 400-Throttling responses from route53,
perform exponential backoff retries on the request.
  • Loading branch information
kyleknap committed Sep 23, 2014
1 parent 445f6bf commit 1af7c05
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
10 changes: 8 additions & 2 deletions boto/route53/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,12 +521,18 @@ def _retry_handler(self, response, i, next_sleep):
if response.status == 400:
code = response.getheader('Code')

if code and 'PriorRequestNotComplete' in code:
if code:
# This is a case where we need to ignore a 400 error, as
# Route53 returns this. See
# http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html
if 'PriorRequestNotComplete' in code:
error = 'PriorRequestNotComplete'
elif 'Throttling' in code:
error = 'Throttling'
else:
return status
msg = "%s, retry attempt %s" % (
'PriorRequestNotComplete',
error,
i
)
next_sleep = min(random.random() * (2 ** i),
Expand Down
17 changes: 14 additions & 3 deletions tests/unit/route53/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,30 @@ def default_body(self):

def test_typical_400(self):
self.set_http_response(status_code=400, header=[
['Code', 'Throttling'],
['Code', 'AccessDenied'],
])

with self.assertRaises(DNSServerError) as err:
self.service_connection.get_all_hosted_zones()

self.assertTrue('It failed.' in str(err.exception))

@mock.patch('time.sleep')
def test_retryable_400(self, sleep_mock):
def test_retryable_400_prior_request_not_complete(self):
# Test ability to retry on ``PriorRequestNotComplete``.
self.set_http_response(status_code=400, header=[
['Code', 'PriorRequestNotComplete'],
])
self.do_retry_handler()

def test_retryable_400_throttling(self):
# Test ability to rety on ``Throttling``.
self.set_http_response(status_code=400, header=[
['Code', 'Throttling'],
])
self.do_retry_handler()

@mock.patch('time.sleep')
def do_retry_handler(self, sleep_mock):

def incr_retry_handler(func):
def _wrapper(*args, **kwargs):
Expand Down

0 comments on commit 1af7c05

Please sign in to comment.