diff --git a/etcdserver/cluster.go b/etcdserver/cluster.go index 1570a7cf5..441f41e8c 100644 --- a/etcdserver/cluster.go +++ b/etcdserver/cluster.go @@ -41,7 +41,8 @@ const ( type ClusterInfo interface { ID() uint64 ClientURLs() []string - Members() map[uint64]*Member + // Members returns a slice of members sorted by their ID + Members() []*Member Member(id uint64) *Member } @@ -123,7 +124,20 @@ func newCluster(name string) *Cluster { func (c Cluster) ID() uint64 { return c.id } -func (c Cluster) Members() map[uint64]*Member { return c.members } +func (c Cluster) Members() []*Member { + var sms SortableMemberSlice + for _, m := range c.members { + sms = append(sms, m) + } + sort.Sort(sms) + return []*Member(sms) +} + +type SortableMemberSlice []*Member + +func (s SortableMemberSlice) Len() int { return len(s) } +func (s SortableMemberSlice) Less(i, j int) bool { return s[i].ID < s[j].ID } +func (s SortableMemberSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (c *Cluster) Member(id uint64) *Member { return c.members[id] diff --git a/etcdserver/cluster_test.go b/etcdserver/cluster_test.go index 1c3de4840..0c398a628 100644 --- a/etcdserver/cluster_test.go +++ b/etcdserver/cluster_test.go @@ -365,6 +365,28 @@ func TestClusterAddMember(t *testing.T) { } } +func TestClusterMembers(t *testing.T) { + cls := &Cluster{ + members: map[uint64]*Member{ + 1: &Member{ID: 1}, + 20: &Member{ID: 20}, + 100: &Member{ID: 100}, + 5: &Member{ID: 5}, + 50: &Member{ID: 50}, + }, + } + w := []*Member{ + &Member{ID: 1}, + &Member{ID: 5}, + &Member{ID: 20}, + &Member{ID: 50}, + &Member{ID: 100}, + } + if g := cls.Members(); !reflect.DeepEqual(g, w) { + t.Fatalf("Members()=%#v, want %#v", g, w) + } +} + func TestClusterRemoveMember(t *testing.T) { st := &storeRecorder{} c := newTestCluster(nil) diff --git a/etcdserver/etcdhttp/http.go b/etcdserver/etcdhttp/http.go index 797d2e65a..13f8e9ff7 100644 --- a/etcdserver/etcdhttp/http.go +++ b/etcdserver/etcdhttp/http.go @@ -25,7 +25,6 @@ import ( "net/http" "net/url" "path" - "sort" "strconv" "strings" "time" @@ -160,12 +159,7 @@ func (h serverHandler) serveAdminMembers(w http.ResponseWriter, r *http.Request) case "GET": idStr := strings.TrimPrefix(r.URL.Path, adminMembersPrefix) if idStr == "" { - msmap := h.clusterInfo.Members() - ms := make(SortableMemberSlice, 0, len(msmap)) - for _, m := range msmap { - ms = append(ms, m) - } - sort.Sort(ms) + ms := h.clusterInfo.Members() w.Header().Set("Content-Type", "application/json") if err := json.NewEncoder(w).Encode(ms); err != nil { log.Printf("etcdhttp: %v", err) @@ -582,9 +576,3 @@ func trimNodeExternPrefix(n *store.NodeExtern, prefix string) *store.NodeExtern } return n } - -type SortableMemberSlice []*etcdserver.Member - -func (s SortableMemberSlice) Len() int { return len(s) } -func (s SortableMemberSlice) Less(i, j int) bool { return s[i].ID < s[j].ID } -func (s SortableMemberSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } diff --git a/etcdserver/etcdhttp/http_test.go b/etcdserver/etcdhttp/http_test.go index c399a2144..30c44942b 100644 --- a/etcdserver/etcdhttp/http_test.go +++ b/etcdserver/etcdhttp/http_test.go @@ -27,6 +27,7 @@ import ( "net/url" "path" "reflect" + "sort" "strings" "testing" "time" @@ -1749,7 +1750,14 @@ type fakeCluster struct { members map[uint64]*etcdserver.Member } -func (c *fakeCluster) ID() uint64 { return c.id } -func (c *fakeCluster) ClientURLs() []string { return c.clientURLs } -func (c *fakeCluster) Members() map[uint64]*etcdserver.Member { return c.members } -func (c *fakeCluster) Member(id uint64) *etcdserver.Member { return c.members[id] } +func (c *fakeCluster) ID() uint64 { return c.id } +func (c *fakeCluster) ClientURLs() []string { return c.clientURLs } +func (c *fakeCluster) Members() []*etcdserver.Member { + var sms etcdserver.SortableMemberSlice + for _, m := range c.members { + sms = append(sms, m) + } + sort.Sort(sms) + return []*etcdserver.Member(sms) +} +func (c *fakeCluster) Member(id uint64) *etcdserver.Member { return c.members[id] }