Skip to content

Commit 848a9cd

Browse files
simorenohealsur
andauthored
[Cosmos] add doc on client retry configs (#30171)
* new doc and small changes to other files * Update _timeout_failover_retry_policy.py * Update _timeout_failover_retry_policy.py * fixing wrong changelog entry * Update CHANGELOG.md * Update ErrorCodesAndRetries.md * Update CHANGELOG.md * Update sdk/cosmos/azure-cosmos/docs/ErrorCodesAndRetries.md Co-authored-by: Matias Quaranta <ealsur@users.noreply.github.com> * Update sdk/cosmos/azure-cosmos/docs/ErrorCodesAndRetries.md Co-authored-by: Matias Quaranta <ealsur@users.noreply.github.com> * additional updates to doc, null check for request on retry policy * small changes, removing /1000 for consistency as well * updated docs with defaults, put in extra logic for request_timeout * Update TimeoutAndRetriesConfig.md --------- Co-authored-by: Matias Quaranta <ealsur@users.noreply.github.com>
1 parent 79080d1 commit 848a9cd

10 files changed

Lines changed: 92 additions & 77 deletions

sdk/cosmos/azure-cosmos/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
#### Breaking Changes
88

99
#### Bugs Fixed
10+
* Fixed bug with non english locales causing an error with the RFC 1123 Date Format. See [PR 30125](https://github.com/Azure/azure-sdk-for-python/pull/30125).
1011

1112
#### Other Changes
13+
* Refactoring of our client `connection_timeout` and `request_timeout` configurations. See [PR 30171](https://github.com/Azure/azure-sdk-for-python/pull/30171).
1214

1315
### 4.4.0b1 (2023-04-11)
1416

@@ -21,7 +23,6 @@
2123
* Fixed bug in method `create_container_if_not_exists()` of async database client for unexpected kwargs being passed into `read()` method used internally. See [PR 29136](https://github.com/Azure/azure-sdk-for-python/pull/29136).
2224
* Fixed bug with method `query_items()` of our async container class, where partition key and cross partition headers would both be set when using partition keys. See [PR 29366](https://github.com/Azure/azure-sdk-for-python/pull/29366/).
2325
* Fixed bug with client not properly surfacing errors for invalid credentials and identities with insufficient permissions. Users running into 'NoneType has no attribute ConsistencyPolicy' errors when initializing their clients will now see proper authentication exceptions. See [PR 29256](https://github.com/Azure/azure-sdk-for-python/pull/29256).
24-
* Fixed bug with non english locales causing an error with the RFC 1123 Date Format. See [PR 30125](https://github.com/Azure/azure-sdk-for-python/pull/30125).
2526

2627
#### Other Changes
2728
* Removed use of `six` package within the SDK.

sdk/cosmos/azure-cosmos/azure/cosmos/_cosmos_client_connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def __init__(
160160
retry_connect=self.connection_policy.ConnectionRetryConfiguration.connect,
161161
retry_read=self.connection_policy.ConnectionRetryConfiguration.read,
162162
retry_status=self.connection_policy.ConnectionRetryConfiguration.status,
163-
retry_backoff_max=self.connection_policy.ConnectionRetryConfiguration.BACKOFF_MAX,
163+
retry_backoff_max=self.connection_policy.ConnectionRetryConfiguration.backoff_max,
164164
retry_on_status_codes=list(self.connection_policy.ConnectionRetryConfiguration.status_forcelist),
165165
retry_backoff_factor=self.connection_policy.ConnectionRetryConfiguration.backoff_factor
166166
)

sdk/cosmos/azure-cosmos/azure/cosmos/_synchronized_request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def _Request(global_endpoint_manager, request_params, connection_policy, pipelin
8484
# pylint: disable=protected-access
8585

8686
connection_timeout = connection_policy.RequestTimeout
87-
connection_timeout = kwargs.pop("connection_timeout", connection_timeout / 1000.0)
87+
connection_timeout = kwargs.pop("connection_timeout", connection_timeout)
8888

8989
# Every request tries to perform a refresh
9090
client_timeout = kwargs.get('timeout')

sdk/cosmos/azure-cosmos/azure/cosmos/_timeout_failover_retry_policy.py

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
Cosmos database service.
2424
"""
2525
from . import http_constants
26-
from ..cosmos.documents import _OperationType
2726

2827

2928
class _TimeoutFailoverRetryPolicy(object):
@@ -38,19 +37,13 @@ def __init__(self, connection_policy, global_endpoint_manager, *args):
3837
self.failover_retry_count = 0
3938
self.connection_policy = connection_policy
4039
self.request = args[0] if args else None
41-
42-
if self.request:
43-
self.request.clear_route_to_location()
44-
45-
# Resolve the endpoint for the request and pin the resolution to the resolved endpoint
46-
# This enables marking the endpoint unavailability on endpoint failover/unreachability
47-
self.location_endpoint = self.global_endpoint_manager.resolve_service_endpoint(self.request)
48-
self.request.route_to_location(self.location_endpoint)
40+
self.location_endpoint = self.global_endpoint_manager.resolve_service_endpoint(self.request)
4941

5042
def needsRetry(self):
5143
if self.args:
5244
if (self.args[3].method == "GET") \
53-
or (http_constants.HttpHeaders.IsQueryPlanRequest in self.args[3].headers):
45+
or http_constants.HttpHeaders.IsQueryPlanRequest in self.args[3].headers\
46+
or http_constants.HttpHeaders.IsQuery in self.args[3].headers:
5447
return True
5548
return False
5649

@@ -75,27 +68,16 @@ def ShouldRetry(self, _exception):
7568

7669
self.failover_retry_count += 1
7770

78-
if self.location_endpoint:
79-
if _OperationType.IsReadOnlyOperation(self.request.operation_type):
80-
# Mark current read endpoint as unavailable
81-
self.global_endpoint_manager.mark_endpoint_unavailable_for_read(self.location_endpoint)
82-
else:
83-
self.global_endpoint_manager.mark_endpoint_unavailable_for_write(self.location_endpoint)
84-
85-
# set the refresh_needed flag to ensure that endpoint list is
86-
# refreshed with new writable and readable locations
87-
self.global_endpoint_manager.refresh_needed = True
88-
89-
# clear previous location-based routing directive
90-
self.request.clear_route_to_location()
71+
if self.request:
72+
# clear previous location-based routing directive
73+
self.request.clear_route_to_location()
9174

92-
# set location-based routing directive based on retry count
93-
# simulating single master writes by ensuring usePreferredLocations
94-
# is set to false
95-
self.request.route_to_location_with_preferred_location_flag(self.failover_retry_count, False)
75+
# set location-based routing directive based on retry count
76+
# ensuring usePreferredLocations is set to True for retry
77+
self.request.route_to_location_with_preferred_location_flag(self.failover_retry_count, True)
9678

97-
# Resolve the endpoint for the request and pin the resolution to the resolved endpoint
98-
# This enables marking the endpoint unavailability on endpoint failover/unreachability
99-
self.location_endpoint = self.global_endpoint_manager.resolve_service_endpoint(self.request)
100-
self.request.route_to_location(self.location_endpoint)
79+
# Resolve the endpoint for the request and pin the resolution to the resolved endpoint
80+
# This enables marking the endpoint unavailability on endpoint failover/unreachability
81+
self.location_endpoint = self.global_endpoint_manager.resolve_service_endpoint(self.request)
82+
self.request.route_to_location(self.location_endpoint)
10183
return True

sdk/cosmos/azure-cosmos/azure/cosmos/aio/_asynchronous_request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ async def _Request(global_endpoint_manager, request_params, connection_policy, p
5353
# pylint: disable=protected-access
5454

5555
connection_timeout = connection_policy.RequestTimeout
56-
connection_timeout = kwargs.pop("connection_timeout", connection_timeout / 1000.0)
56+
connection_timeout = kwargs.pop("connection_timeout", connection_timeout)
5757

5858
# Every request tries to perform a refresh
5959
client_timeout = kwargs.get('timeout')

sdk/cosmos/azure-cosmos/azure/cosmos/aio/_cosmos_client.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,31 +45,32 @@ def _build_connection_policy(kwargs: Dict[str, Any]) -> ConnectionPolicy:
4545
policy = kwargs.pop('connection_policy', None) or ConnectionPolicy()
4646

4747
# Connection config
48-
policy.RequestTimeout = kwargs.pop('request_timeout', None) or \
49-
kwargs.pop('connection_timeout', None) or \
50-
policy.RequestTimeout
51-
policy.ConnectionMode = kwargs.pop('connection_mode', None) or policy.ConnectionMode
52-
policy.ProxyConfiguration = kwargs.pop('proxy_config', None) or policy.ProxyConfiguration
53-
policy.EnableEndpointDiscovery = kwargs.pop('enable_endpoint_discovery', None) or policy.EnableEndpointDiscovery
54-
policy.PreferredLocations = kwargs.pop('preferred_locations', None) or policy.PreferredLocations
55-
policy.UseMultipleWriteLocations = kwargs.pop('multiple_write_locations', None) or \
56-
policy.UseMultipleWriteLocations
48+
# `request_timeout` is supported as a legacy parameter later replaced by `connection_timeout`
49+
if 'request_timeout' in kwargs:
50+
policy.RequestTimeout = kwargs.pop('request_timeout') / 1000.0
51+
else:
52+
policy.RequestTimeout = kwargs.pop('connection_timeout', policy.RequestTimeout)
53+
policy.ConnectionMode = kwargs.pop('connection_mode', policy.ConnectionMode)
54+
policy.ProxyConfiguration = kwargs.pop('proxy_config', policy.ProxyConfiguration)
55+
policy.EnableEndpointDiscovery = kwargs.pop('enable_endpoint_discovery', policy.EnableEndpointDiscovery)
56+
policy.PreferredLocations = kwargs.pop('preferred_locations', policy.PreferredLocations)
57+
policy.UseMultipleWriteLocations = kwargs.pop('multiple_write_locations', policy.UseMultipleWriteLocations)
5758

5859
# SSL config
5960
verify = kwargs.pop('connection_verify', None)
6061
policy.DisableSSLVerification = not bool(verify if verify is not None else True)
6162
ssl = kwargs.pop('ssl_config', None) or policy.SSLConfiguration
6263
if ssl:
63-
ssl.SSLCertFile = kwargs.pop('connection_cert', None) or ssl.SSLCertFile
64+
ssl.SSLCertFile = kwargs.pop('connection_cert', ssl.SSLCertFile)
6465
ssl.SSLCaCerts = verify or ssl.SSLCaCerts
6566
policy.SSLConfiguration = ssl
6667

6768
# Retry config
6869
retry_options = policy.RetryOptions
6970
total_retries = kwargs.pop('retry_total', None)
7071
retry_options._max_retry_attempt_count = total_retries or retry_options._max_retry_attempt_count
71-
retry_options._fixed_retry_interval_in_milliseconds = kwargs.pop('retry_fixed_interval', None) or \
72-
retry_options._fixed_retry_interval_in_milliseconds
72+
retry_options._fixed_retry_interval_in_milliseconds = \
73+
kwargs.pop('retry_fixed_interval', retry_options._fixed_retry_interval_in_milliseconds)
7374
max_backoff = kwargs.pop('retry_backoff_max', None)
7475
retry_options._max_wait_time_in_seconds = max_backoff or retry_options._max_wait_time_in_seconds
7576
policy.RetryOptions = retry_options
@@ -100,7 +101,7 @@ class CosmosClient(object): # pylint: disable=client-accepts-api-version-keywor
100101
:keyword str consistency_level: Consistency level to use for the session. Default value is None (account-level).
101102
More on consistency levels and possible values: https://aka.ms/cosmos-consistency-levels
102103
:keyword int timeout: An absolute timeout in seconds, for the combined HTTP request and response processing.
103-
:keyword int request_timeout: The HTTP request timeout in milliseconds.
104+
:keyword int connection_timeout: The HTTP request timeout in seconds.
104105
:keyword str connection_mode: The connection mode for the client - currently only supports 'Gateway'.
105106
:keyword proxy_config: Connection proxy configuration.
106107
:paramtype proxy_config: ~azure.cosmos.ProxyConfiguration

sdk/cosmos/azure-cosmos/azure/cosmos/cosmos_client.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -74,26 +74,26 @@ def _build_auth(credential):
7474
def _build_connection_policy(kwargs):
7575
# type: (Dict[str, Any]) -> ConnectionPolicy
7676
# pylint: disable=protected-access
77-
policy = kwargs.pop('connection_policy', None) or ConnectionPolicy()
77+
policy = kwargs.pop('connection_policy', ConnectionPolicy())
7878

7979
# Connection config
80-
policy.RequestTimeout = kwargs.pop('request_timeout', None) or \
81-
kwargs.pop('connection_timeout', None) or \
82-
policy.RequestTimeout
83-
policy.ConnectionMode = kwargs.pop('connection_mode', None) or policy.ConnectionMode
84-
policy.ProxyConfiguration = kwargs.pop('proxy_config', None) or policy.ProxyConfiguration
85-
policy.EnableEndpointDiscovery = kwargs.pop('enable_endpoint_discovery') \
86-
if 'enable_endpoint_discovery' in kwargs.keys() else policy.EnableEndpointDiscovery
87-
policy.PreferredLocations = kwargs.pop('preferred_locations', None) or policy.PreferredLocations
88-
policy.UseMultipleWriteLocations = kwargs.pop('multiple_write_locations', None) or \
89-
policy.UseMultipleWriteLocations
80+
# `request_timeout` is supported as a legacy parameter later replaced by `connection_timeout`
81+
if 'request_timeout' in kwargs:
82+
policy.RequestTimeout = kwargs.pop('request_timeout') / 1000.0
83+
else:
84+
policy.RequestTimeout = kwargs.pop('connection_timeout', policy.RequestTimeout)
85+
policy.ConnectionMode = kwargs.pop('connection_mode', policy.ConnectionMode)
86+
policy.ProxyConfiguration = kwargs.pop('proxy_config', policy.ProxyConfiguration)
87+
policy.EnableEndpointDiscovery = kwargs.pop('enable_endpoint_discovery', policy.EnableEndpointDiscovery)
88+
policy.PreferredLocations = kwargs.pop('preferred_locations', policy.PreferredLocations)
89+
policy.UseMultipleWriteLocations = kwargs.pop('multiple_write_locations', policy.UseMultipleWriteLocations)
9090

9191
# SSL config
9292
verify = kwargs.pop('connection_verify', None)
9393
policy.DisableSSLVerification = not bool(verify if verify is not None else True)
94-
ssl = kwargs.pop('ssl_config', None) or policy.SSLConfiguration
94+
ssl = kwargs.pop('ssl_config', policy.SSLConfiguration)
9595
if ssl:
96-
ssl.SSLCertFile = kwargs.pop('connection_cert', None) or ssl.SSLCertFile
96+
ssl.SSLCertFile = kwargs.pop('connection_cert', ssl.SSLCertFile)
9797
ssl.SSLCaCerts = verify or ssl.SSLCaCerts
9898
policy.SSLConfiguration = ssl
9999

@@ -141,7 +141,7 @@ class CosmosClient(object): # pylint: disable=client-accepts-api-version-keywor
141141
:param str consistency_level: Consistency level to use for the session. The default value is None (Account level).
142142
More on consistency levels and possible values: https://aka.ms/cosmos-consistency-levels
143143
:keyword int timeout: An absolute timeout in seconds, for the combined HTTP request and response processing.
144-
:keyword int request_timeout: The HTTP request timeout in milliseconds.
144+
:keyword int connection_timeout: The HTTP request timeout in seconds.
145145
:keyword str connection_mode: The connection mode for the client - currently only supports 'Gateway'.
146146
:keyword proxy_config: Connection proxy configuration.
147147
:paramtype proxy_config: ~azure.cosmos.ProxyConfiguration

sdk/cosmos/azure-cosmos/azure/cosmos/documents.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ class ConnectionPolicy(object): # pylint: disable=too-many-instance-attributes
358358
int or azure.cosmos.ConnectionRetryPolicy or urllib3.util.retry
359359
"""
360360

361-
__defaultRequestTimeout = 60000 # milliseconds
361+
__defaultRequestTimeout = 60 # seconds
362362

363363
def __init__(self):
364364
self.RequestTimeout = self.__defaultRequestTimeout

0 commit comments

Comments
 (0)