@@ -1237,8 +1237,6 @@ def _execute_command(self, target_node, *args, **kwargs):
12371237 except AuthenticationError :
12381238 raise
12391239 except (ConnectionError , TimeoutError ) as e :
1240- # Connection retries are being handled in the node's
1241- # Retry object.
12421240 # ConnectionError can also be raised if we couldn't get a
12431241 # connection from the pool before timing out, so check that
12441242 # this is an actual connection before attempting to disconnect.
@@ -1854,7 +1852,7 @@ def remap_host_port(self, host: str, port: int) -> Tuple[str, int]:
18541852
18551853 def find_connection_owner (self , connection : Connection ) -> Optional [Redis ]:
18561854 node_name = get_node_name (connection .host , connection .port )
1857- for node in self .nodes_cache .values ():
1855+ for node in tuple ( self .nodes_cache .values () ):
18581856 if node .redis_connection :
18591857 conn_args = node .redis_connection .connection_pool .connection_kwargs
18601858 if node_name == get_node_name (
@@ -2550,7 +2548,7 @@ def multi(self):
25502548 """
25512549 Starts transactional context.
25522550
2553- See: ClusterPipeline.reset ()
2551+ See: ClusterPipeline.multi ()
25542552 """
25552553 pass
25562554
@@ -2706,9 +2704,9 @@ def send_cluster_commands(
27062704 self , stack , raise_on_error = True , allow_redirections = True
27072705 ):
27082706 """
2709- Wrapper for CLUSTERDOWN error handling.
2707+ Wrapper for RedisCluster.ERRORS_ALLOW_RETRY errors handling.
27102708
2711- If the cluster reports it is down it is assumed that:
2709+ If one of the retryable exceptions has been thrown we assume that:
27122710 - connection_pool was disconnected
27132711 - connection_pool was reseted
27142712 - refereh_table_asap set to True
@@ -2816,11 +2814,10 @@ def _send_cluster_commands(
28162814 # we write to all the open sockets for each node first,
28172815 # before reading anything
28182816 # this allows us to flush all the requests out across the
2819- # network essentially in parallel
2820- # so that we can read them all in parallel as they come back.
2817+ # network
2818+ # so that we can read them from different sockets as they come back.
28212819 # we dont' multiplex on the sockets as they come available,
28222820 # but that shouldn't make too much difference.
2823- node_commands = nodes .values ()
28242821 try :
28252822 node_commands = nodes .values ()
28262823 for n in node_commands :
@@ -3024,7 +3021,7 @@ class TransactionStrategy(AbstractStrategy):
30243021 IMMEDIATE_EXECUTE_COMMANDS = {"WATCH" , "UNWATCH" }
30253022 UNWATCH_COMMANDS = {"DISCARD" , "EXEC" , "UNWATCH" }
30263023 SLOT_REDIRECT_ERRORS = (AskError , MovedError )
3027- CONNECTION_ERRORS = (ConnectionError ,OSError ,ClusterDownError )
3024+ CONNECTION_ERRORS = (ConnectionError , OSError , ClusterDownError )
30283025
30293026 def __init__ (self , pipe : ClusterPipeline ):
30303027 super ().__init__ (pipe )
@@ -3033,6 +3030,10 @@ def __init__(self, pipe: ClusterPipeline):
30333030 self ._pipeline_slots : Set [int ] = set ()
30343031 self ._transaction_connection : Optional [Connection ] = None
30353032 self ._executing = False
3033+ self ._retry = copy (self ._pipe .retry )
3034+ self ._retry .update_supported_errors (
3035+ RedisCluster .ERRORS_ALLOW_RETRY + self .SLOT_REDIRECT_ERRORS
3036+ )
30363037
30373038 def _get_client_and_connection_for_transaction (self ) -> Tuple [Redis , Connection ]:
30383039 """
@@ -3105,9 +3106,7 @@ def _validate_watch(self):
31053106 self ._watching = True
31063107
31073108 def _immediate_execute_command (self , * args , ** options ):
3108- retry = copy (self ._pipe .retry )
3109- retry .update_supported_errors ([AskError , MovedError ])
3110- return retry .call_with_retry (
3109+ return self ._retry .call_with_retry (
31113110 lambda : self ._get_connection_and_send_command (* args , ** options ),
31123111 self ._reinitialize_on_error ,
31133112 )
@@ -3137,7 +3136,10 @@ def _reinitialize_on_error(self, error):
31373136 if type (error ) in self .SLOT_REDIRECT_ERRORS and self ._executing :
31383137 raise WatchError ("Slot rebalancing occurred while watching keys" )
31393138
3140- if type (error ) in self .SLOT_REDIRECT_ERRORS or type (error ) in self .CONNECTION_ERRORS :
3139+ if (
3140+ type (error ) in self .SLOT_REDIRECT_ERRORS
3141+ or type (error ) in self .CONNECTION_ERRORS
3142+ ):
31413143 if self ._transaction_connection :
31423144 self ._transaction_connection = None
31433145
@@ -3169,9 +3171,7 @@ def execute(self, raise_on_error: bool = True) -> List[Any]:
31693171 def _execute_transaction_with_retries (
31703172 self , stack : List ["PipelineCommand" ], raise_on_error : bool
31713173 ):
3172- retry = copy (self ._pipe .retry )
3173- retry .update_supported_errors ([AskError , MovedError ])
3174- return retry .call_with_retry (
3174+ return self ._retry .call_with_retry (
31753175 lambda : self ._execute_transaction (stack , raise_on_error ),
31763176 self ._reinitialize_on_error ,
31773177 )
0 commit comments