diff options
author | Mike Crute <mcrute@gmail.com> | 2016-01-25 19:12:35 -0800 |
---|---|---|
committer | Mike Crute <mcrute@gmail.com> | 2016-01-25 19:12:35 -0800 |
commit | aef95e84ae59259e49adbe45b2c5327dab52d097 (patch) | |
tree | c2377e9cca89f1df73dc6970c07b7f024ecb2c67 | |
parent | c5353abd5594a14b2cbdb713fe6855ec467659ab (diff) | |
parent | 9c298b18519a3cf41c7c1566c52f68b55324c010 (diff) | |
download | pydora-aef95e84ae59259e49adbe45b2c5327dab52d097.tar.bz2 pydora-aef95e84ae59259e49adbe45b2c5327dab52d097.tar.xz pydora-aef95e84ae59259e49adbe45b2c5327dab52d097.zip |
Merge pull request #42 from jcass77/develop
Fix to avoid retries on PandoraExceptions
-rw-r--r-- | pandora/transport.py | 12 | ||||
-rw-r--r-- | tests/test_pandora/test_transport.py | 32 |
2 files changed, 37 insertions, 7 deletions
diff --git a/pandora/transport.py b/pandora/transport.py index 8fab7af..58d4097 100644 --- a/pandora/transport.py +++ b/pandora/transport.py | |||
@@ -50,14 +50,12 @@ def retries(max_tries, exceptions=(Exception,)): | |||
50 | # Don't retry for PandoraExceptions - unlikely that result | 50 | # Don't retry for PandoraExceptions - unlikely that result |
51 | # will change for same set of input parameters. | 51 | # will change for same set of input parameters. |
52 | if isinstance(e, PandoraException): | 52 | if isinstance(e, PandoraException): |
53 | continue | 53 | raise |
54 | if retries_left > 0: | 54 | if retries_left > 0: |
55 | time.sleep(delay_exponential( | 55 | time.sleep(delay_exponential( |
56 | 0.5, 2, max_tries - retries_left)) | 56 | 0.5, 2, max_tries - retries_left)) |
57 | else: | 57 | else: |
58 | raise | 58 | raise |
59 | else: | ||
60 | break | ||
61 | 59 | ||
62 | return function | 60 | return function |
63 | 61 | ||
@@ -88,14 +86,14 @@ class RetryingSession(requests.Session): | |||
88 | """Requests Session With Retry Support | 86 | """Requests Session With Retry Support |
89 | 87 | ||
90 | This Requests session uses an HTTPAdapter that retries on connection | 88 | This Requests session uses an HTTPAdapter that retries on connection |
91 | failure at least once. The Pandora API is fairly aggressive about closing | 89 | failure three times. The Pandora API is fairly aggressive about closing |
92 | connections on clients and the default session doesn't retry. | 90 | connections on clients and the default session doesn't retry. |
93 | """ | 91 | """ |
94 | 92 | ||
95 | def __init__(self): | 93 | def __init__(self): |
96 | super(RetryingSession, self).__init__() | 94 | super(RetryingSession, self).__init__() |
97 | self.mount('https://', HTTPAdapter(max_retries=1)) | 95 | self.mount('https://', HTTPAdapter(max_retries=3)) |
98 | self.mount('http://', HTTPAdapter(max_retries=1)) | 96 | self.mount('http://', HTTPAdapter(max_retries=3)) |
99 | 97 | ||
100 | 98 | ||
101 | class APITransport(object): | 99 | class APITransport(object): |
@@ -226,7 +224,7 @@ class APITransport(object): | |||
226 | # TODO: This decorator is a temporary workaround for handling | 224 | # TODO: This decorator is a temporary workaround for handling |
227 | # SysCallErrors, see: https://github.com/shazow/urllib3/issues/367. | 225 | # SysCallErrors, see: https://github.com/shazow/urllib3/issues/367. |
228 | # Should be removed once a fix is applied in urllib3. | 226 | # Should be removed once a fix is applied in urllib3. |
229 | @retries(5) | 227 | @retries(3) |
230 | def __call__(self, method, **data): | 228 | def __call__(self, method, **data): |
231 | self._start_request(method) | 229 | self._start_request(method) |
232 | 230 | ||
diff --git a/tests/test_pandora/test_transport.py b/tests/test_pandora/test_transport.py index 6596a0e..1393b7d 100644 --- a/tests/test_pandora/test_transport.py +++ b/tests/test_pandora/test_transport.py | |||
@@ -1,5 +1,6 @@ | |||
1 | import time | 1 | import time |
2 | from unittest import TestCase | 2 | from unittest import TestCase |
3 | from pandora.errors import InvalidAuthToken, PandoraException | ||
3 | 4 | ||
4 | from pandora.py2compat import Mock, call | 5 | from pandora.py2compat import Mock, call |
5 | 6 | ||
@@ -25,3 +26,34 @@ class TestTransport(TestCase): | |||
25 | 26 | ||
26 | client.transport._start_request.assert_has_calls([call("method")]) | 27 | client.transport._start_request.assert_has_calls([call("method")]) |
27 | assert client.transport._start_request.call_count == 5 | 28 | assert client.transport._start_request.call_count == 5 |
29 | |||
30 | def test_call_should_not_retry_for_pandora_exceptions(self): | ||
31 | with self.assertRaises(PandoraException): | ||
32 | client = TestSettingsDictBuilder._build_minimal() | ||
33 | |||
34 | time.sleep = Mock() | ||
35 | client.transport._make_http_request = Mock( | ||
36 | side_effect=PandoraException("error_mock")) | ||
37 | client.transport._start_request = Mock() | ||
38 | |||
39 | client("method") | ||
40 | |||
41 | client.transport._start_request.assert_has_calls([call("method")]) | ||
42 | assert client.transport._start_request.call_count == 1 | ||
43 | |||
44 | def test_call_should_retry_if_auth_token_expired(self): | ||
45 | with self.assertRaises(InvalidAuthToken): | ||
46 | client = TestSettingsDictBuilder._build_minimal() | ||
47 | |||
48 | time.sleep = Mock() | ||
49 | client.transport._make_http_request = Mock( | ||
50 | side_effect=InvalidAuthToken("error_mock")) | ||
51 | client.transport._start_request = Mock() | ||
52 | |||
53 | client._authenticate = Mock() | ||
54 | |||
55 | client("method") | ||
56 | |||
57 | client.transport._start_request.assert_has_calls([call("method")]) | ||
58 | assert client.transport._start_request.call_count == 2 | ||
59 | assert client._authenticate.call_count == 1 | ||