func ParseCluster()

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
}