in store/cluster.go [252:319]
func ParseCluster(clusterStr string) (*Cluster, error) {
if len(clusterStr) == 0 {
return nil, errors.New("cluster nodes string error")
}
nodeStrings := strings.Split(clusterStr, "\n")
if len(nodeStrings) == 0 {
return nil, errors.New("cluster nodes string parser error")
}
var clusterVer int64 = -1
var shards Shards
slaveNodes := make(map[string][]Node)
for _, nodeString := range nodeStrings {
fields := strings.Split(nodeString, " ")
if len(fields) < 7 {
return nil, fmt.Errorf("require at least 7 fields, node info[%s]", nodeString)
}
node := &ClusterNode{
id: fields[0],
addr: strings.Split(fields[1], "@")[0],
}
if strings.Contains(fields[2], ",") {
node.role = strings.Split(fields[2], ",")[1]
} else {
node.role = fields[2]
}
var err error
clusterVer, err = strconv.ParseInt(fields[6], 10, 64)
if err != nil {
return nil, fmt.Errorf("node version error, node info[%q]", nodeString)
}
if node.role == RoleMaster {
shard := NewShard()
shard.Nodes = append(shard.Nodes, node)
// remain fields are slot ranges
for i := 8; i < len(fields); i++ {
slotRange, err := ParseSlotRange(fields[i])
if err != nil {
return nil, fmt.Errorf("parse slots error for node[%s]: %w", nodeString, err)
}
shard.SlotRanges = append(shard.SlotRanges, *slotRange)
}
shards = append(shards, shard)
} else if node.role == RoleSlave {
slaveNodes[fields[3]] = append(slaveNodes[fields[3]], node)
} else {
return nil, fmt.Errorf("node role error, node info[%q]", nodeString)
}
}
if clusterVer == -1 {
return nil, fmt.Errorf("no cluster version, cluster info[%q]", clusterStr)
}
sort.Sort(shards)
for i := 0; i < len(shards); i++ {
masterNode := shards[i].Nodes[0]
shards[i].Nodes = append(shards[i].Nodes, slaveNodes[masterNode.ID()]...)
}
clusterInfo := &Cluster{
Shards: shards,
}
clusterInfo.Version.Store(clusterVer)
return clusterInfo, nil
}