From 4b9c3a910268c943e4fc1cffab43b451474729f8 Mon Sep 17 00:00:00 2001 From: Yicheng Qin Date: Sat, 8 Nov 2014 12:07:23 -0800 Subject: [PATCH] etcdserver: not get cluster info from self peer urls Self peer urls have not started to serve at the time that it tries to get cluster info, so it is useless to get cluster info from self peer urls. --- etcdserver/server.go | 18 ++++++++++++++++- etcdserver/server_test.go | 41 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/etcdserver/server.go b/etcdserver/server.go index 677285767..97b125fcf 100644 --- a/etcdserver/server.go +++ b/etcdserver/server.go @@ -27,6 +27,7 @@ import ( "os" "path" "regexp" + "sort" "sync/atomic" "time" @@ -193,7 +194,8 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { haveWAL := wal.Exist(cfg.WALDir()) switch { case !haveWAL && !cfg.NewCluster: - cl, err := GetClusterFromPeers(cfg.Cluster.PeerURLs()) + us := getOtherPeerURLs(cfg.Cluster, cfg.Name) + cl, err := GetClusterFromPeers(us) if err != nil { return nil, fmt.Errorf("cannot fetch cluster info from peer urls: %v", err) } @@ -748,6 +750,20 @@ func startNode(cfg *ServerConfig, ids []types.ID) (id types.ID, n raft.Node, w * return } +// getOtherPeerURLs returns peer urls of other members in the cluster. The +// returned list is sorted in ascending lexicographical order. +func getOtherPeerURLs(cl ClusterInfo, self string) []string { + us := make([]string, 0) + for _, m := range cl.Members() { + if m.Name == self { + continue + } + us = append(us, m.PeerURLs...) + } + sort.Strings(us) + return us +} + func restartNode(cfg *ServerConfig, index uint64, snapshot *raftpb.Snapshot) (id types.ID, n raft.Node, w *wal.WAL) { var err error // restart a node from previous wal diff --git a/etcdserver/server_test.go b/etcdserver/server_test.go index 8caa1ad7f..25fa25bc9 100644 --- a/etcdserver/server_test.go +++ b/etcdserver/server_test.go @@ -1093,6 +1093,47 @@ func TestPublishRetry(t *testing.T) { } } +func TestGetOtherPeerURLs(t *testing.T) { + tests := []struct { + membs []*Member + self string + wurls []string + }{ + { + []*Member{ + newTestMemberp(1, []string{"http://10.0.0.1"}, "a", nil), + }, + "a", + []string{}, + }, + { + []*Member{ + newTestMemberp(1, []string{"http://10.0.0.1"}, "a", nil), + newTestMemberp(2, []string{"http://10.0.0.2"}, "b", nil), + newTestMemberp(3, []string{"http://10.0.0.3"}, "c", nil), + }, + "a", + []string{"http://10.0.0.2", "http://10.0.0.3"}, + }, + { + []*Member{ + newTestMemberp(1, []string{"http://10.0.0.1"}, "a", nil), + newTestMemberp(3, []string{"http://10.0.0.3"}, "c", nil), + newTestMemberp(2, []string{"http://10.0.0.2"}, "b", nil), + }, + "a", + []string{"http://10.0.0.2", "http://10.0.0.3"}, + }, + } + for i, tt := range tests { + cl := NewClusterFromMembers("", types.ID(0), tt.membs) + urls := getOtherPeerURLs(cl, tt.self) + if !reflect.DeepEqual(urls, tt.wurls) { + t.Errorf("#%d: urls = %+v, want %+v", i, urls, tt.wurls) + } + } +} + func TestGetBool(t *testing.T) { tests := []struct { b *bool