admin: only claim fallback master leadership on an empty raft response

A nonempty RaftListClusterServers response whose entries were all
rejected left masterMap empty, so the fallback marked the reachable
current master as leader the same way a genuinely empty (non-raft)
response does. Track whether the successful response returned zero
servers and only promote the fallback master then.
This commit is contained in:
Chris Lu committed 2026-09-18 12:22:39 -07:00
1 parent bd41ce39f7
commit 934b9b4daf
2 files changed
+11 -6

No files matched your search

+5 -4
View File
@@ -282,7 +282,7 @@ func (s *AdminServer) ShowOverview(w http.ResponseWriter, r *http.Request) {
// dashboard never shows an empty list.
func (s *AdminServer) getMasterNodesStatus() []MasterNode {
masterMap := make(map[string]MasterNode)
raftCallSucceeded := false
raftReturnedEmpty := false
err := s.WithMasterClient(func(client master_pb.SeaweedClient) error {
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
@@ -291,7 +291,7 @@ func (s *AdminServer) getMasterNodesStatus() []MasterNode {
if err != nil {
return err
}
raftCallSucceeded = true
raftReturnedEmpty = len(resp.ClusterServers) == 0
for _, server := range resp.ClusterServers {
// Skip malformed raft addresses instead of letting an
// unconvertible value into masterMap.
@@ -323,10 +323,11 @@ func (s *AdminServer) getMasterNodesStatus() []MasterNode {
addr := pb.ServerAddress(currentMaster).ToHttpAddress()
// A successful empty raft response means raft is not initialized
// (standalone/non-raft cluster); the only master IS the leader.
// A failed RPC means connectivity issue; do not claim leadership.
// A failed RPC or a nonempty response whose entries were all
// rejected must not claim leadership.
masterMap[addr] = MasterNode{
Address: addr,
IsLeader: raftCallSucceeded,
IsLeader: raftReturnedEmpty,
}
}
}
+6 -2
View File
@@ -1341,11 +1341,13 @@ func (s *AdminServer) GetClusterMasters() (*ClusterMastersData, error) {
}
// Then, get additional master information from Raft cluster
raftReturnedEmpty := false
err = s.WithMasterClient(func(client master_pb.SeaweedClient) error {
resp, err := client.RaftListClusterServers(context.Background(), &master_pb.RaftListClusterServersRequest{})
if err != nil {
return err
}
raftReturnedEmpty = len(resp.ClusterServers) == 0
// Process each raft server
for _, server := range resp.ClusterServers {
@@ -1401,10 +1403,12 @@ func (s *AdminServer) GetClusterMasters() (*ClusterMastersData, error) {
if currentMaster != "" {
masters = append(masters, MasterInfo{
Address: pb.ServerAddress(currentMaster).ToHttpAddress(),
IsLeader: true,
IsLeader: raftReturnedEmpty,
Suffrage: "Voter",
})
leaderCount = 1
if raftReturnedEmpty {
leaderCount = 1
}
}
}