@@ -2737,7 +2737,7 @@ def __init__(
2737
2737
):
2738
2738
self ._last_error : Optional [Exception ] = None
2739
2739
self ._retrying = False
2740
- self ._overloaded = False
2740
+ self ._always_retryable = False
2741
2741
self ._multiple_retries = _csot .get_timeout () is not None
2742
2742
self ._client = mongo_client
2743
2743
@@ -2786,14 +2786,16 @@ async def run(self) -> T:
2786
2786
# most likely be a waste of time.
2787
2787
raise
2788
2788
except PyMongoError as exc :
2789
+ always_retryable = False
2789
2790
overloaded = False
2790
2791
# Execute specialized catch on read
2791
2792
if self ._is_read :
2792
2793
if isinstance (exc , (ConnectionFailure , OperationFailure )):
2793
2794
# ConnectionFailures do not supply a code property
2794
2795
exc_code = getattr (exc , "code" , None )
2795
- overloaded = exc .has_error_label ("Retryable" )
2796
- if not overloaded and (
2796
+ always_retryable = exc .has_error_label ("Retryable" )
2797
+ overloaded = exc .has_error_label ("SystemOverloaded" )
2798
+ if not always_retryable and (
2797
2799
self ._is_not_eligible_for_retry ()
2798
2800
or (
2799
2801
isinstance (exc , OperationFailure )
@@ -2810,21 +2812,22 @@ async def run(self) -> T:
2810
2812
# Specialized catch on write operation
2811
2813
if not self ._is_read :
2812
2814
if isinstance (exc , ClientBulkWriteException ) and exc .error :
2813
- retryable_write_error_exc = isinstance (
2814
- exc .error , PyMongoError
2815
- ) and exc . error . has_error_label ( "RetryableWriteError" )
2816
- overloaded = isinstance (
2817
- exc .error , PyMongoError
2818
- ) and exc .error .has_error_label ("Retryable " )
2815
+ if isinstance (exc . error , PyMongoError ):
2816
+ retryable_write_error_exc = exc .error . has_error_label (
2817
+ "RetryableWriteError"
2818
+ )
2819
+ always_retryable = exc .error . has_error_label ( "Retryable" )
2820
+ overloaded = exc .error .has_error_label ("SystemOverloaded " )
2819
2821
else :
2820
2822
retryable_write_error_exc = exc .has_error_label ("RetryableWriteError" )
2821
- overloaded = exc .has_error_label ("Retryable" )
2822
- if not self ._retryable and not overloaded :
2823
+ always_retryable = exc .has_error_label ("Retryable" )
2824
+ overloaded = exc .has_error_label ("SystemOverloaded" )
2825
+ if not self ._retryable and not always_retryable :
2823
2826
raise
2824
- if retryable_write_error_exc or overloaded :
2827
+ if retryable_write_error_exc or always_retryable :
2825
2828
assert self ._session
2826
2829
await self ._session ._unpin ()
2827
- if not overloaded and (
2830
+ if not always_retryable and (
2828
2831
not retryable_write_error_exc or not self ._is_not_eligible_for_retry ()
2829
2832
):
2830
2833
if exc .has_error_label ("NoWritesPerformed" ) and self ._last_error :
@@ -2844,14 +2847,15 @@ async def run(self) -> T:
2844
2847
if self ._client .topology_description .topology_type == TOPOLOGY_TYPE .Sharded :
2845
2848
self ._deprioritized_servers .append (self ._server )
2846
2849
2847
- self ._overloaded = overloaded
2848
- if overloaded :
2850
+ self ._always_retryable = always_retryable
2851
+ if always_retryable :
2849
2852
if self ._attempt_number > _MAX_RETRIES :
2850
2853
if exc .has_error_label ("NoWritesPerformed" ) and self ._last_error :
2851
2854
raise self ._last_error from exc
2852
2855
else :
2853
2856
raise
2854
- await _backoff (self ._attempt_number )
2857
+ if overloaded :
2858
+ await _backoff (self ._attempt_number )
2855
2859
2856
2860
def _is_not_eligible_for_retry (self ) -> bool :
2857
2861
"""Checks if the exchange is not eligible for retry"""
@@ -2946,7 +2950,7 @@ async def _read(self) -> T:
2946
2950
conn ,
2947
2951
read_pref ,
2948
2952
):
2949
- if self ._retrying and not self ._retryable and not self ._overloaded :
2953
+ if self ._retrying and not self ._retryable and not self ._always_retryable :
2950
2954
self ._check_last_error ()
2951
2955
if self ._retrying :
2952
2956
_debug_log (
0 commit comments