From 04c6565e816e60b9ee0f004eb1cc206ae08998cb Mon Sep 17 00:00:00 2001 From: Bar Shaul Date: Mon, 20 Dec 2021 14:56:48 +0200 Subject: [PATCH 1/2] Fixed 'MovedError' bug in RedisCluster, changed the initialize function of the nodes manager to stop iterating through startup nodes when the coverage is full --- redis/cluster.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/redis/cluster.py b/redis/cluster.py index b1adeb7341..1fbe822efb 100644 --- a/redis/cluster.py +++ b/redis/cluster.py @@ -996,9 +996,11 @@ def _execute_command(self, target_node, *args, **kwargs): self.reinitialize_counter += 1 if self._should_reinitialized(): self.nodes_manager.initialize() + # Reset the counter + self.reinitialize_counter = 0 else: self.nodes_manager.update_moved_exception(e) - moved = True + moved = True except TryAgainError: log.exception("TryAgainError") @@ -1320,6 +1322,7 @@ def initialize(self): tmp_slots = {} disagreements = [] startup_nodes_reachable = False + fully_covered = False kwargs = self.connection_kwargs for startup_node in self.startup_nodes.values(): try: @@ -1431,6 +1434,11 @@ def initialize(self): f'slots cache: {", ".join(disagreements)}' ) + fully_covered = self.check_slots_coverage(tmp_slots) + if fully_covered: + # Don't need to continue to the next startup node if all slots are covered + break + if not startup_nodes_reachable: raise RedisClusterException( "Redis Cluster cannot be connected. Please provide at least " @@ -1440,7 +1448,6 @@ def initialize(self): # Create Redis connections to all nodes self.create_redis_connections(list(tmp_nodes_cache.values())) - fully_covered = self.check_slots_coverage(tmp_slots) # Check if the slots are not fully covered if not fully_covered and self._require_full_coverage: # Despite the requirement that the slots be covered, there @@ -1478,6 +1485,8 @@ def initialize(self): self.default_node = self.get_nodes_by_server_type(PRIMARY)[0] # Populate the startup nodes with all discovered nodes self.populate_startup_nodes(self.nodes_cache.values()) + # If initialize was called after a MovedError, clear it + self._moved_exception = None def close(self): self.default_node = None From 21ff2b4ff0005fb62c143fef21ee7406f663caf1 Mon Sep 17 00:00:00 2001 From: Bar Shaul Date: Mon, 20 Dec 2021 15:05:52 +0200 Subject: [PATCH 2/2] Fixed linetrs --- redis/cluster.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/redis/cluster.py b/redis/cluster.py index 1fbe822efb..0c2fc715d7 100644 --- a/redis/cluster.py +++ b/redis/cluster.py @@ -1436,7 +1436,8 @@ def initialize(self): fully_covered = self.check_slots_coverage(tmp_slots) if fully_covered: - # Don't need to continue to the next startup node if all slots are covered + # Don't need to continue to the next startup node if all + # slots are covered break if not startup_nodes_reachable: