@@ -2737,7 +2737,7 @@ def __init__(
27372737 ):
27382738 self ._last_error : Optional [Exception ] = None
27392739 self ._retrying = False
2740- self ._overloaded = False
2740+ self ._always_retryable = False
27412741 self ._multiple_retries = _csot .get_timeout () is not None
27422742 self ._client = mongo_client
27432743
@@ -2786,14 +2786,16 @@ async def run(self) -> T:
27862786 # most likely be a waste of time.
27872787 raise
27882788 except PyMongoError as exc :
2789+ always_retryable = False
27892790 overloaded = False
27902791 # Execute specialized catch on read
27912792 if self ._is_read :
27922793 if isinstance (exc , (ConnectionFailure , OperationFailure )):
27932794 # ConnectionFailures do not supply a code property
27942795 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 (
27972799 self ._is_not_eligible_for_retry ()
27982800 or (
27992801 isinstance (exc , OperationFailure )
@@ -2810,21 +2812,22 @@ async def run(self) -> T:
28102812 # Specialized catch on write operation
28112813 if not self ._is_read :
28122814 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 " )
28192821 else :
28202822 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 :
28232826 raise
2824- if retryable_write_error_exc or overloaded :
2827+ if retryable_write_error_exc or always_retryable :
28252828 assert self ._session
28262829 await self ._session ._unpin ()
2827- if not overloaded and (
2830+ if not always_retryable and (
28282831 not retryable_write_error_exc or not self ._is_not_eligible_for_retry ()
28292832 ):
28302833 if exc .has_error_label ("NoWritesPerformed" ) and self ._last_error :
@@ -2844,14 +2847,15 @@ async def run(self) -> T:
28442847 if self ._client .topology_description .topology_type == TOPOLOGY_TYPE .Sharded :
28452848 self ._deprioritized_servers .append (self ._server )
28462849
2847- self ._overloaded = overloaded
2848- if overloaded :
2850+ self ._always_retryable = always_retryable
2851+ if always_retryable :
28492852 if self ._attempt_number > _MAX_RETRIES :
28502853 if exc .has_error_label ("NoWritesPerformed" ) and self ._last_error :
28512854 raise self ._last_error from exc
28522855 else :
28532856 raise
2854- await _backoff (self ._attempt_number )
2857+ if overloaded :
2858+ await _backoff (self ._attempt_number )
28552859
28562860 def _is_not_eligible_for_retry (self ) -> bool :
28572861 """Checks if the exchange is not eligible for retry"""
@@ -2946,7 +2950,7 @@ async def _read(self) -> T:
29462950 conn ,
29472951 read_pref ,
29482952 ):
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 :
29502954 self ._check_last_error ()
29512955 if self ._retrying :
29522956 _debug_log (
0 commit comments