You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							151 lines
						
					
					
						
							4.3 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							151 lines
						
					
					
						
							4.3 KiB
						
					
					
				| package cluster | |
| 
 | |
| import ( | |
| 	"github.com/seaweedfs/seaweedfs/weed/pb" | |
| 	"github.com/seaweedfs/seaweedfs/weed/pb/master_pb" | |
| 	"sync" | |
| 	"time" | |
| ) | |
| 
 | |
| const ( | |
| 	MasterType       = "master" | |
| 	VolumeServerType = "volumeServer" | |
| 	FilerType        = "filer" | |
| 	BrokerType       = "broker" | |
| ) | |
| 
 | |
| type FilerGroupName string | |
| type DataCenter string | |
| type Rack string | |
| 
 | |
| type ClusterNode struct { | |
| 	Address    pb.ServerAddress | |
| 	Version    string | |
| 	counter    int | |
| 	CreatedTs  time.Time | |
| 	DataCenter DataCenter | |
| 	Rack       Rack | |
| } | |
| 
 | |
| type ClusterNodeGroups struct { | |
| 	groupMembers map[FilerGroupName]*GroupMembers | |
| 	sync.RWMutex | |
| } | |
| type Cluster struct { | |
| 	filerGroups  *ClusterNodeGroups | |
| 	brokerGroups *ClusterNodeGroups | |
| } | |
| 
 | |
| func newClusterNodeGroups() *ClusterNodeGroups { | |
| 	return &ClusterNodeGroups{ | |
| 		groupMembers: map[FilerGroupName]*GroupMembers{}, | |
| 	} | |
| } | |
| func (g *ClusterNodeGroups) getGroupMembers(filerGroup FilerGroupName, createIfNotFound bool) *GroupMembers { | |
| 	members, found := g.groupMembers[filerGroup] | |
| 	if !found && createIfNotFound { | |
| 		members = newGroupMembers() | |
| 		g.groupMembers[filerGroup] = members | |
| 	} | |
| 	return members | |
| } | |
| 
 | |
| func (g *ClusterNodeGroups) AddClusterNode(filerGroup FilerGroupName, nodeType string, dataCenter DataCenter, rack Rack, address pb.ServerAddress, version string) []*master_pb.KeepConnectedResponse { | |
| 	g.Lock() | |
| 	defer g.Unlock() | |
| 	m := g.getGroupMembers(filerGroup, true) | |
| 	if t := m.addMember(dataCenter, rack, address, version); t != nil { | |
| 		return buildClusterNodeUpdateMessage(true, filerGroup, nodeType, address) | |
| 	} | |
| 	return nil | |
| } | |
| func (g *ClusterNodeGroups) RemoveClusterNode(filerGroup FilerGroupName, nodeType string, address pb.ServerAddress) []*master_pb.KeepConnectedResponse { | |
| 	g.Lock() | |
| 	defer g.Unlock() | |
| 	m := g.getGroupMembers(filerGroup, false) | |
| 	if m == nil { | |
| 		return nil | |
| 	} | |
| 	if m.removeMember(address) { | |
| 		return buildClusterNodeUpdateMessage(false, filerGroup, nodeType, address) | |
| 	} | |
| 	return nil | |
| } | |
| func (g *ClusterNodeGroups) ListClusterNode(filerGroup FilerGroupName) (nodes []*ClusterNode) { | |
| 	g.Lock() | |
| 	defer g.Unlock() | |
| 	m := g.getGroupMembers(filerGroup, false) | |
| 	if m == nil { | |
| 		return nil | |
| 	} | |
| 	for _, node := range m.members { | |
| 		nodes = append(nodes, node) | |
| 	} | |
| 	return | |
| } | |
| 
 | |
| func NewCluster() *Cluster { | |
| 	return &Cluster{ | |
| 		filerGroups:  newClusterNodeGroups(), | |
| 		brokerGroups: newClusterNodeGroups(), | |
| 	} | |
| } | |
| 
 | |
| func (cluster *Cluster) getGroupMembers(filerGroup FilerGroupName, nodeType string, createIfNotFound bool) *GroupMembers { | |
| 	switch nodeType { | |
| 	case FilerType: | |
| 		return cluster.filerGroups.getGroupMembers(filerGroup, createIfNotFound) | |
| 	case BrokerType: | |
| 		return cluster.brokerGroups.getGroupMembers(filerGroup, createIfNotFound) | |
| 	} | |
| 	return nil | |
| } | |
| 
 | |
| func (cluster *Cluster) AddClusterNode(ns, nodeType string, dataCenter DataCenter, rack Rack, address pb.ServerAddress, version string) []*master_pb.KeepConnectedResponse { | |
| 	filerGroup := FilerGroupName(ns) | |
| 	switch nodeType { | |
| 	case FilerType: | |
| 		return cluster.filerGroups.AddClusterNode(filerGroup, nodeType, dataCenter, rack, address, version) | |
| 	case BrokerType: | |
| 		return cluster.brokerGroups.AddClusterNode(filerGroup, nodeType, dataCenter, rack, address, version) | |
| 	case MasterType: | |
| 		return buildClusterNodeUpdateMessage(true, filerGroup, nodeType, address) | |
| 	} | |
| 	return nil | |
| } | |
| 
 | |
| func (cluster *Cluster) RemoveClusterNode(ns string, nodeType string, address pb.ServerAddress) []*master_pb.KeepConnectedResponse { | |
| 	filerGroup := FilerGroupName(ns) | |
| 	switch nodeType { | |
| 	case FilerType: | |
| 		return cluster.filerGroups.RemoveClusterNode(filerGroup, nodeType, address) | |
| 	case BrokerType: | |
| 		return cluster.brokerGroups.RemoveClusterNode(filerGroup, nodeType, address) | |
| 	case MasterType: | |
| 		return buildClusterNodeUpdateMessage(false, filerGroup, nodeType, address) | |
| 	} | |
| 	return nil | |
| } | |
| 
 | |
| func (cluster *Cluster) ListClusterNode(filerGroup FilerGroupName, nodeType string) (nodes []*ClusterNode) { | |
| 	switch nodeType { | |
| 	case FilerType: | |
| 		return cluster.filerGroups.ListClusterNode(filerGroup) | |
| 	case BrokerType: | |
| 		return cluster.brokerGroups.ListClusterNode(filerGroup) | |
| 	case MasterType: | |
| 	} | |
| 	return | |
| } | |
| 
 | |
| func buildClusterNodeUpdateMessage(isAdd bool, filerGroup FilerGroupName, nodeType string, address pb.ServerAddress) (result []*master_pb.KeepConnectedResponse) { | |
| 	result = append(result, &master_pb.KeepConnectedResponse{ | |
| 		ClusterNodeUpdate: &master_pb.ClusterNodeUpdate{ | |
| 			FilerGroup: string(filerGroup), | |
| 			NodeType:   nodeType, | |
| 			Address:    string(address), | |
| 			IsAdd:      isAdd, | |
| 		}, | |
| 	}) | |
| 	return | |
| }
 |