Skip to content

Commit 0676892

Browse files
barshauldvora-h
andauthored
Extended "CLUSTER NODES" parser to support special slot entries (importing, migrating). (#2080)
See https://redis.io/commands/cluster-nodes/#special-slot-entries Co-authored-by: dvora-h <[email protected]>
1 parent e6968f8 commit 0676892

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

redis/client.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -466,26 +466,49 @@ def _parse_node_line(line):
466466
line_items = line.split(" ")
467467
node_id, addr, flags, master_id, ping, pong, epoch, connected = line.split(" ")[:8]
468468
addr = addr.split("@")[0]
469-
slots = [sl.split("-") for sl in line_items[8:]]
470469
node_dict = {
471470
"node_id": node_id,
472471
"flags": flags,
473472
"master_id": master_id,
474473
"last_ping_sent": ping,
475474
"last_pong_rcvd": pong,
476475
"epoch": epoch,
477-
"slots": slots,
476+
"slots": [],
477+
"migrations": [],
478478
"connected": True if connected == "connected" else False,
479479
}
480+
if len(line_items) >= 9:
481+
slots, migrations = _parse_slots(line_items[8:])
482+
node_dict["slots"], node_dict["migrations"] = slots, migrations
480483
return addr, node_dict
481484

482485

486+
def _parse_slots(slot_ranges):
487+
slots, migrations = [], []
488+
for s_range in slot_ranges:
489+
if "->-" in s_range:
490+
slot_id, dst_node_id = s_range[1:-1].split("->-", 1)
491+
migrations.append(
492+
{"slot": slot_id, "node_id": dst_node_id, "state": "migrating"}
493+
)
494+
elif "-<-" in s_range:
495+
slot_id, src_node_id = s_range[1:-1].split("-<-", 1)
496+
migrations.append(
497+
{"slot": slot_id, "node_id": src_node_id, "state": "importing"}
498+
)
499+
else:
500+
s_range = [sl for sl in s_range.split("-")]
501+
slots.append(s_range)
502+
503+
return slots, migrations
504+
505+
483506
def parse_cluster_nodes(response, **options):
484507
"""
485-
@see: https://redis.io/commands/cluster-nodes # string
486-
@see: https://redis.io/commands/cluster-replicas # list of string
508+
@see: https://redis.io/commands/cluster-nodes # string / bytes
509+
@see: https://redis.io/commands/cluster-replicas # list of string / bytes
487510
"""
488-
if isinstance(response, str):
511+
if isinstance(response, (str, bytes)):
489512
response = response.splitlines()
490513
return dict(_parse_node_line(str_if_bytes(node)) for node in response)
491514

tests/test_cluster.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,43 @@ def test_cluster_nodes(self, r):
967967
== "c8253bae761cb1ecb2b61857d85dfe455a0fec8b"
968968
)
969969

970+
@skip_if_redis_enterprise()
971+
def test_cluster_nodes_importing_migrating(self, r):
972+
response = (
973+
"488ead2fcce24d8c0f158f9172cb1f4a9e040fe5 127.0.0.1:16381@26381 "
974+
"master - 0 1648975557664 3 connected 10923-16383\n"
975+
"8ae2e70812db80776f739a72374e57fc4ae6f89d 127.0.0.1:16380@26380 "
976+
"master - 0 1648975555000 2 connected 1 5461-10922 ["
977+
"2-<-ed8007ccfa2d91a7b76f8e6fba7ba7e257034a16]\n"
978+
"ed8007ccfa2d91a7b76f8e6fba7ba7e257034a16 127.0.0.1:16379@26379 "
979+
"myself,master - 0 1648975556000 1 connected 0 2-5460 ["
980+
"2->-8ae2e70812db80776f739a72374e57fc4ae6f89d]\n"
981+
)
982+
mock_all_nodes_resp(r, response)
983+
nodes = r.cluster_nodes()
984+
assert len(nodes) == 3
985+
node_16379 = nodes.get("127.0.0.1:16379")
986+
node_16380 = nodes.get("127.0.0.1:16380")
987+
node_16381 = nodes.get("127.0.0.1:16381")
988+
assert node_16379.get("migrations") == [
989+
{
990+
"slot": "2",
991+
"node_id": "8ae2e70812db80776f739a72374e57fc4ae6f89d",
992+
"state": "migrating",
993+
}
994+
]
995+
assert node_16379.get("slots") == [["0"], ["2", "5460"]]
996+
assert node_16380.get("migrations") == [
997+
{
998+
"slot": "2",
999+
"node_id": "ed8007ccfa2d91a7b76f8e6fba7ba7e257034a16",
1000+
"state": "importing",
1001+
}
1002+
]
1003+
assert node_16380.get("slots") == [["1"], ["5461", "10922"]]
1004+
assert node_16381.get("slots") == [["10923", "16383"]]
1005+
assert node_16381.get("migrations") == []
1006+
9701007
@skip_if_redis_enterprise()
9711008
def test_cluster_replicate(self, r):
9721009
node = r.get_random_node()

0 commit comments

Comments
 (0)