Skip to content

Commit cf47d68

Browse files
BorysTheDevromange
authored andcommitted
feat: allow cluster READONLY command (#4727)
* feat: allow cluster READONLY command
1 parent 86e1201 commit cf47d68

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

src/server/cluster/cluster_family.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,6 @@ void ClusterFamily::Cluster(CmdArgList args, const CommandContext& cmd_cntx) {
446446
}
447447

448448
void ClusterFamily::ReadOnly(CmdArgList args, const CommandContext& cmd_cntx) {
449-
if (!IsClusterEmulated()) {
450-
return cmd_cntx.rb->SendError(kClusterDisabled);
451-
}
452449
cmd_cntx.rb->SendOk();
453450
}
454451

tests/dragonfly/cluster_test.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2890,3 +2890,44 @@ async def do_migration(index):
28902890
await seed
28912891
capture = await seeder.capture_fake_redis()
28922892
assert await seeder.compare(capture, nodes[1].instance.port)
2893+
2894+
2895+
@dfly_args({"proactor_threads": 4, "cluster_mode": "yes"})
2896+
async def test_readonly_replication(
2897+
df_factory: DflyInstanceFactory, df_seeder_factory: DflySeederFactory
2898+
):
2899+
# create cluster master and replica
2900+
# For now replica always should work in read-only mode
2901+
# READONLY command returns always OK without any impact
2902+
# In the future we may decide to implement the same behavior as REDIS
2903+
instances = [
2904+
df_factory.create(port=next(next_port), admin_port=next(next_port)) for i in range(2)
2905+
]
2906+
df_factory.start_all(instances)
2907+
2908+
nodes = [await create_node_info(n) for n in instances]
2909+
m1_node, r1_node = nodes
2910+
master_nodes = [m1_node]
2911+
2912+
m1_node.slots = [(0, 16383)]
2913+
m1_node.replicas = [r1_node]
2914+
2915+
logging.debug("Push initial config")
2916+
await push_config(
2917+
json.dumps(generate_config(master_nodes)), [node.admin_client for node in nodes]
2918+
)
2919+
2920+
logging.debug("create data")
2921+
await m1_node.client.execute_command("SET X 1")
2922+
2923+
logging.debug("start replication")
2924+
await r1_node.admin_client.execute_command(f"replicaof localhost {m1_node.instance.port}")
2925+
2926+
await wait_available_async(r1_node.admin_client)
2927+
2928+
assert await r1_node.client.execute_command("GET X") == "1"
2929+
assert await r1_node.client.execute_command("READONLY")
2930+
assert await r1_node.client.execute_command("GET X") == "1"
2931+
2932+
# This behavior can be changed in the future
2933+
assert await r1_node.client.execute_command("GET Y") == None

0 commit comments

Comments
 (0)