summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongkeun Lee <3315213+zakaf@users.noreply.github.com>2023-01-11 18:29:11 +0900
committerGitHub <noreply@github.com>2023-01-11 11:29:11 +0200
commitbae6385c1b0097a1d85c7825604170477d193481 (patch)
treec9375cd81abe76b57b0d40526a4dd0564b521667
parent4a825bc76b668951923c57aaff1020c3892f8de2 (diff)
downloadredis-py-bae6385c1b0097a1d85c7825604170477d193481.tar.gz
allow replica to master promotion in nodes_cache (#2549)
Co-authored-by: zach.lee <zach.lee@sendbird.com>
-rw-r--r--redis/cluster.py2
-rw-r--r--tests/test_cluster.py51
2 files changed, 53 insertions, 0 deletions
diff --git a/redis/cluster.py b/redis/cluster.py
index f115007..235d8f2 100644
--- a/redis/cluster.py
+++ b/redis/cluster.py
@@ -1437,6 +1437,8 @@ class NodesManager:
if target_node is None or target_node.redis_connection is None:
# create new cluster node for this cluster
target_node = ClusterNode(host, port, role)
+ if target_node.server_type != role:
+ target_node.server_type = role
return target_node
diff --git a/tests/test_cluster.py b/tests/test_cluster.py
index 27cfee1..55b660c 100644
--- a/tests/test_cluster.py
+++ b/tests/test_cluster.py
@@ -2262,6 +2262,57 @@ class TestNodesManager:
assert len(n_manager.nodes_cache) == 6
+ def test_init_promote_server_type_for_node_in_cache(self):
+ """
+ When replica is promoted to master, nodes_cache must change the server type
+ accordingly
+ """
+ cluster_slots_before_promotion = [
+ [0, 16383, ["127.0.0.1", 7000], ["127.0.0.1", 7003]]
+ ]
+ cluster_slots_after_promotion = [
+ [0, 16383, ["127.0.0.1", 7003], ["127.0.0.1", 7004]]
+ ]
+
+ cluster_slots_results = [
+ cluster_slots_before_promotion,
+ cluster_slots_after_promotion,
+ ]
+
+ with patch.object(Redis, "execute_command") as execute_command_mock:
+
+ def execute_command(*_args, **_kwargs):
+ if _args[0] == "CLUSTER SLOTS":
+ mock_cluster_slots = cluster_slots_results.pop(0)
+ return mock_cluster_slots
+ elif _args[0] == "COMMAND":
+ return {"get": [], "set": []}
+ elif _args[0] == "INFO":
+ return {"cluster_enabled": True}
+ elif len(_args) > 1 and _args[1] == "cluster-require-full-coverage":
+ return {"cluster-require-full-coverage": False}
+ else:
+ return execute_command_mock(*_args, **_kwargs)
+
+ execute_command_mock.side_effect = execute_command
+
+ nm = NodesManager(
+ startup_nodes=[ClusterNode(host=default_host, port=default_port)],
+ from_url=False,
+ require_full_coverage=False,
+ dynamic_startup_nodes=True,
+ )
+
+ assert nm.default_node.host == "127.0.0.1"
+ assert nm.default_node.port == 7000
+ assert nm.default_node.server_type == PRIMARY
+
+ nm.initialize()
+
+ assert nm.default_node.host == "127.0.0.1"
+ assert nm.default_node.port == 7003
+ assert nm.default_node.server_type == PRIMARY
+
def test_init_slots_cache_cluster_mode_disabled(self):
"""
Test that creating a RedisCluster failes if one of the startup nodes