Fix admin GUI list ordering on refresh (#7782)
Sort lists of filers, volume servers, masters, and message brokers by address to ensure consistent ordering on page refresh. This fixes the non-deterministic ordering caused by iterating over Go maps with range. Fixes #7781
This commit is contained in:
@@ -109,13 +109,6 @@ func (s *AdminServer) GetAdminData(username string) (AdminData, error) {
|
|||||||
glog.Errorf("Failed to get cluster volume servers: %v", err)
|
glog.Errorf("Failed to get cluster volume servers: %v", err)
|
||||||
return AdminData{}, err
|
return AdminData{}, err
|
||||||
}
|
}
|
||||||
// Sort the servers so they show up in consistent order after each reload
|
|
||||||
sort.Slice(volumeServersData.VolumeServers, func(i, j int) bool {
|
|
||||||
s1Name := volumeServersData.VolumeServers[i].GetDisplayAddress()
|
|
||||||
s2Name := volumeServersData.VolumeServers[j].GetDisplayAddress()
|
|
||||||
|
|
||||||
return s1Name < s2Name
|
|
||||||
})
|
|
||||||
|
|
||||||
// Get master nodes status
|
// Get master nodes status
|
||||||
masterNodes := s.getMasterNodesStatus()
|
masterNodes := s.getMasterNodesStatus()
|
||||||
@@ -265,6 +258,11 @@ func (s *AdminServer) getFilerNodesStatus() []FilerNode {
|
|||||||
return []FilerNode{}
|
return []FilerNode{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort filer nodes by address for consistent ordering on page refresh
|
||||||
|
sort.Slice(filerNodes, func(i, j int) bool {
|
||||||
|
return filerNodes[i].Address < filerNodes[j].Address
|
||||||
|
})
|
||||||
|
|
||||||
return filerNodes
|
return filerNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,5 +299,10 @@ func (s *AdminServer) getMessageBrokerNodesStatus() []MessageBrokerNode {
|
|||||||
return []MessageBrokerNode{}
|
return []MessageBrokerNode{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort message broker nodes by address for consistent ordering on page refresh
|
||||||
|
sort.Slice(messageBrokers, func(i, j int) bool {
|
||||||
|
return messageBrokers[i].Address < messageBrokers[j].Address
|
||||||
|
})
|
||||||
|
|
||||||
return messageBrokers
|
return messageBrokers
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -720,6 +721,11 @@ func (s *AdminServer) GetClusterMasters() (*ClusterMastersData, error) {
|
|||||||
masters = append(masters, *masterInfo)
|
masters = append(masters, *masterInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort masters by address for consistent ordering on page refresh
|
||||||
|
sort.Slice(masters, func(i, j int) bool {
|
||||||
|
return masters[i].Address < masters[j].Address
|
||||||
|
})
|
||||||
|
|
||||||
// If no masters found at all, add the current master as fallback
|
// If no masters found at all, add the current master as fallback
|
||||||
if len(masters) == 0 {
|
if len(masters) == 0 {
|
||||||
currentMaster := s.masterClient.GetMaster(context.Background())
|
currentMaster := s.masterClient.GetMaster(context.Background())
|
||||||
@@ -776,6 +782,11 @@ func (s *AdminServer) GetClusterFilers() (*ClusterFilersData, error) {
|
|||||||
return nil, fmt.Errorf("failed to get filer nodes from master: %w", err)
|
return nil, fmt.Errorf("failed to get filer nodes from master: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort filers by address for consistent ordering on page refresh
|
||||||
|
sort.Slice(filers, func(i, j int) bool {
|
||||||
|
return filers[i].Address < filers[j].Address
|
||||||
|
})
|
||||||
|
|
||||||
return &ClusterFilersData{
|
return &ClusterFilersData{
|
||||||
Filers: filers,
|
Filers: filers,
|
||||||
TotalFilers: len(filers),
|
TotalFilers: len(filers),
|
||||||
@@ -818,6 +829,11 @@ func (s *AdminServer) GetClusterBrokers() (*ClusterBrokersData, error) {
|
|||||||
return nil, fmt.Errorf("failed to get broker nodes from master: %w", err)
|
return nil, fmt.Errorf("failed to get broker nodes from master: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort brokers by address for consistent ordering on page refresh
|
||||||
|
sort.Slice(brokers, func(i, j int) bool {
|
||||||
|
return brokers[i].Address < brokers[j].Address
|
||||||
|
})
|
||||||
|
|
||||||
return &ClusterBrokersData{
|
return &ClusterBrokersData{
|
||||||
Brokers: brokers,
|
Brokers: brokers,
|
||||||
TotalBrokers: len(brokers),
|
TotalBrokers: len(brokers),
|
||||||
|
|||||||
@@ -544,6 +544,11 @@ func (s *AdminServer) GetClusterVolumeServers() (*ClusterVolumeServersData, erro
|
|||||||
volumeServers = append(volumeServers, *vs)
|
volumeServers = append(volumeServers, *vs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort volume servers by address for consistent ordering on page refresh
|
||||||
|
sort.Slice(volumeServers, func(i, j int) bool {
|
||||||
|
return volumeServers[i].GetDisplayAddress() < volumeServers[j].GetDisplayAddress()
|
||||||
|
})
|
||||||
|
|
||||||
var totalCapacity int64
|
var totalCapacity int64
|
||||||
var totalVolumes int
|
var totalVolumes int
|
||||||
for _, vs := range volumeServers {
|
for _, vs := range volumeServers {
|
||||||
|
|||||||
Reference in New Issue
Block a user