Skip to content

Commit 12c1ba3

Browse files
chlowellrakshith91
authored andcommitted
Retry policies don't sleep after operations time out (Azure#18548)
1 parent 7087273 commit 12c1ba3

File tree

4 files changed

+61
-4
lines changed

4 files changed

+61
-4
lines changed

sdk/core/azure-core/azure/core/pipeline/policies/_retry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ def send(self, request):
455455
# succeed--we'll never have a response to it, so propagate the exception
456456
raise
457457
except AzureError as err:
458-
if self._is_method_retryable(retry_settings, request.http_request):
458+
if absolute_timeout > 0 and self._is_method_retryable(retry_settings, request.http_request):
459459
retry_active = self.increment(retry_settings, response=request, error=err)
460460
if retry_active:
461461
self.sleep(retry_settings, request.context.transport)

sdk/core/azure-core/azure/core/pipeline/policies/_retry_async.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ async def send(self, request): # pylint:disable=invalid-overridden-method
157157
# succeed--we'll never have a response to it, so propagate the exception
158158
raise
159159
except AzureError as err:
160-
if self._is_method_retryable(retry_settings, request.http_request):
160+
if absolute_timeout > 0 and self._is_method_retryable(retry_settings, request.http_request):
161161
retry_active = self.increment(retry_settings, response=request, error=err)
162162
if retry_active:
163163
await self.sleep(retry_settings, request.context.transport)

sdk/core/azure-core/tests/async_tests/test_retry_policy_async.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@
1111
from unittest.mock import Mock
1212
import pytest
1313
from azure.core.configuration import ConnectionConfiguration
14-
from azure.core.exceptions import AzureError, ServiceResponseError, ServiceResponseTimeoutError
14+
from azure.core.exceptions import (
15+
AzureError,
16+
ServiceRequestError,
17+
ServiceRequestTimeoutError,
18+
ServiceResponseError,
19+
ServiceResponseTimeoutError
20+
)
1521
from azure.core.pipeline.policies import (
1622
AsyncRetryPolicy,
1723
RetryMode,
@@ -258,3 +264,26 @@ async def send(request, **kwargs):
258264

259265
await pipeline.run(HttpRequest("GET", "http://127.0.0.1/"))
260266
assert transport.send.call_count == 1, "policy should not retry: its first send succeeded"
267+
268+
269+
@pytest.mark.asyncio
270+
@pytest.mark.parametrize(
271+
"transport_error,expected_timeout_error",
272+
((ServiceRequestError, ServiceRequestTimeoutError), (ServiceResponseError, ServiceResponseTimeoutError)),
273+
)
274+
async def test_does_not_sleep_after_timeout(transport_error, expected_timeout_error):
275+
# With default settings policy will sleep twice before exhausting its retries: 1.6s, 3.2s.
276+
# It should not sleep the second time when given timeout=1
277+
timeout = 1
278+
279+
transport = Mock(
280+
spec=AsyncHttpTransport,
281+
send=Mock(side_effect=transport_error("oops")),
282+
sleep=Mock(wraps=asyncio.sleep),
283+
)
284+
pipeline = AsyncPipeline(transport, [AsyncRetryPolicy(timeout=timeout)])
285+
286+
with pytest.raises(expected_timeout_error):
287+
await pipeline.run(HttpRequest("GET", "http://127.0.0.1/"))
288+
289+
assert transport.sleep.call_count == 1

sdk/core/azure-core/tests/test_retry_policy.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,13 @@
99
from cStringIO import StringIO as BytesIO
1010
import pytest
1111
from azure.core.configuration import ConnectionConfiguration
12-
from azure.core.exceptions import AzureError, ServiceResponseError, ServiceResponseTimeoutError
12+
from azure.core.exceptions import (
13+
AzureError,
14+
ServiceRequestError,
15+
ServiceRequestTimeoutError,
16+
ServiceResponseError,
17+
ServiceResponseTimeoutError,
18+
)
1319
from azure.core.pipeline.policies import (
1420
RetryPolicy,
1521
RetryMode,
@@ -255,3 +261,25 @@ def send(request, **kwargs):
255261

256262
pipeline.run(HttpRequest("GET", "http://127.0.0.1/"))
257263
assert transport.send.call_count == 1, "policy should not retry: its first send succeeded"
264+
265+
266+
@pytest.mark.parametrize(
267+
"transport_error,expected_timeout_error",
268+
((ServiceRequestError, ServiceRequestTimeoutError), (ServiceResponseError, ServiceResponseTimeoutError)),
269+
)
270+
def test_does_not_sleep_after_timeout(transport_error, expected_timeout_error):
271+
# With default settings policy will sleep twice before exhausting its retries: 1.6s, 3.2s.
272+
# It should not sleep the second time when given timeout=1
273+
timeout = 1
274+
275+
transport = Mock(
276+
spec=HttpTransport,
277+
send=Mock(side_effect=transport_error("oops")),
278+
sleep=Mock(wraps=time.sleep),
279+
)
280+
pipeline = Pipeline(transport, [RetryPolicy(timeout=timeout)])
281+
282+
with pytest.raises(expected_timeout_error):
283+
pipeline.run(HttpRequest("GET", "http://127.0.0.1/"))
284+
285+
assert transport.sleep.call_count == 1

0 commit comments

Comments
 (0)