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.
92 lines
2.8 KiB
92 lines
2.8 KiB
package weed_server
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/raft"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/cluster"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
|
)
|
|
|
|
func (ms *MasterServer) RaftListClusterServers(ctx context.Context, req *master_pb.RaftListClusterServersRequest) (*master_pb.RaftListClusterServersResponse, error) {
|
|
resp := &master_pb.RaftListClusterServersResponse{}
|
|
|
|
ms.Topo.RaftServerAccessLock.RLock()
|
|
if ms.Topo.HashicorpRaft == nil {
|
|
ms.Topo.RaftServerAccessLock.RUnlock()
|
|
return resp, nil
|
|
}
|
|
|
|
servers := ms.Topo.HashicorpRaft.GetConfiguration().Configuration().Servers
|
|
_, leaderId := ms.Topo.HashicorpRaft.LeaderWithID()
|
|
ms.Topo.RaftServerAccessLock.RUnlock()
|
|
|
|
for _, server := range servers {
|
|
resp.ClusterServers = append(resp.ClusterServers, &master_pb.RaftListClusterServersResponse_ClusterServers{
|
|
Id: string(server.ID),
|
|
Address: string(server.Address),
|
|
Suffrage: server.Suffrage.String(),
|
|
IsLeader: server.ID == leaderId,
|
|
})
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (ms *MasterServer) RaftAddServer(ctx context.Context, req *master_pb.RaftAddServerRequest) (*master_pb.RaftAddServerResponse, error) {
|
|
resp := &master_pb.RaftAddServerResponse{}
|
|
|
|
ms.Topo.RaftServerAccessLock.RLock()
|
|
defer ms.Topo.RaftServerAccessLock.RUnlock()
|
|
|
|
if ms.Topo.HashicorpRaft == nil {
|
|
return resp, nil
|
|
}
|
|
|
|
if ms.Topo.HashicorpRaft.State() != raft.Leader {
|
|
return nil, fmt.Errorf("raft add server %s failed: %s is no current leader", req.Id, ms.Topo.HashicorpRaft.String())
|
|
}
|
|
|
|
var idxFuture raft.IndexFuture
|
|
if req.Voter {
|
|
idxFuture = ms.Topo.HashicorpRaft.AddVoter(raft.ServerID(req.Id), raft.ServerAddress(req.Address), 0, 0)
|
|
} else {
|
|
idxFuture = ms.Topo.HashicorpRaft.AddNonvoter(raft.ServerID(req.Id), raft.ServerAddress(req.Address), 0, 0)
|
|
}
|
|
|
|
if err := idxFuture.Error(); err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (ms *MasterServer) RaftRemoveServer(ctx context.Context, req *master_pb.RaftRemoveServerRequest) (*master_pb.RaftRemoveServerResponse, error) {
|
|
resp := &master_pb.RaftRemoveServerResponse{}
|
|
|
|
ms.Topo.RaftServerAccessLock.RLock()
|
|
defer ms.Topo.RaftServerAccessLock.RUnlock()
|
|
|
|
if ms.Topo.HashicorpRaft == nil {
|
|
return resp, nil
|
|
}
|
|
|
|
if ms.Topo.HashicorpRaft.State() != raft.Leader {
|
|
return nil, fmt.Errorf("raft remove server %s failed: %s is no current leader", req.Id, ms.Topo.HashicorpRaft.String())
|
|
}
|
|
|
|
if !req.Force {
|
|
ms.clientChansLock.RLock()
|
|
_, ok := ms.clientChans[fmt.Sprintf("%s@%s", cluster.MasterType, req.Id)]
|
|
ms.clientChansLock.RUnlock()
|
|
if ok {
|
|
return resp, fmt.Errorf("raft remove server %s failed: client connection to master exists", req.Id)
|
|
}
|
|
}
|
|
|
|
idxFuture := ms.Topo.HashicorpRaft.RemoveServer(raft.ServerID(req.Id), 0, 0)
|
|
if err := idxFuture.Error(); err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|