Skip to content

Commit 699f8f6

Browse files
committed
Don't deplete all the startup nodes after a series of ConnectionError or TimeoutError against all nodes, rather keep one around so that retry algorithm has at least one node to work with
1 parent 513c8d0 commit 699f8f6

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

redis/asyncio/cluster.py

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -816,16 +816,28 @@ async def _execute_command(
816816
return await target_node.execute_command(*args, **kwargs)
817817
except (BusyLoadingError, MaxConnectionsError):
818818
raise
819-
except (ConnectionError, TimeoutError):
820-
# Connection retries are being handled in the node's
821-
# Retry object.
822-
# Remove the failed node from the startup nodes before we try
823-
# to reinitialize the cluster
824-
self.nodes_manager.startup_nodes.pop(target_node.name, None)
819+
except (ConnectionError, TimeoutError) as e:
820+
if len(self.nodes_manager.startup_nodes) == 1:
821+
# keep at least one node for retrying
822+
ce = RedisClusterException(
823+
'Redis Cluster cannot be connected. '
824+
'Connection or Timeout Errors across all startup nodes'
825+
)
826+
ce.__cause__ = e
827+
e = ce
828+
else:
829+
# Connection retries are being handled in the node's
830+
# Retry object.
831+
# Remove the failed node from the startup nodes before we
832+
# try to reinitialize the cluster
833+
self.nodes_manager.startup_nodes.pop(
834+
target_node.name,
835+
None
836+
)
825837
# Hard force of reinitialize of the node/slots setup
826838
# and try again with the new setup
827839
await self.aclose()
828-
raise
840+
raise e
829841
except (ClusterDownError, SlotNotCoveredError):
830842
# ClusterDownError can occur during a failover and to get
831843
# self-healed, we will try to reinitialize the cluster layout

0 commit comments

Comments
 (0)