mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
server: refactor add
This commit is contained in:
parent
3ea913e76a
commit
83e1fe77c8
44
etcd/etcd.go
44
etcd/etcd.go
@ -42,7 +42,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
removeTmpErr = fmt.Errorf("remove: try again")
|
tmpErr = fmt.Errorf("try again")
|
||||||
serverStopErr = fmt.Errorf("server is stopped")
|
serverStopErr = fmt.Errorf("server is stopped")
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -199,7 +199,6 @@ func (s *Server) Join() {
|
|||||||
|
|
||||||
func (s *Server) Add(id int64, raftPubAddr string, pubAddr string) error {
|
func (s *Server) Add(id int64, raftPubAddr string, pubAddr string) error {
|
||||||
p := path.Join(v2machineKVPrefix, fmt.Sprint(id))
|
p := path.Join(v2machineKVPrefix, fmt.Sprint(id))
|
||||||
index := s.Index()
|
|
||||||
|
|
||||||
_, err := s.Get(p, false, false)
|
_, err := s.Get(p, false, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -208,26 +207,33 @@ func (s *Server) Add(id int64, raftPubAddr string, pubAddr string) error {
|
|||||||
if v, ok := err.(*etcdErr.Error); !ok || v.ErrorCode != etcdErr.EcodeKeyNotFound {
|
if v, ok := err.(*etcdErr.Error); !ok || v.ErrorCode != etcdErr.EcodeKeyNotFound {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for {
|
|
||||||
|
w, err := s.Watch(p, true, false, 0)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("add error:", err)
|
||||||
|
return tmpErr
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case s.addNodeC <- raft.Config{NodeId: id, Addr: raftPubAddr, Context: []byte(pubAddr)}:
|
case s.addNodeC <- raft.Config{NodeId: id, Addr: raftPubAddr, Context: []byte(pubAddr)}:
|
||||||
case <-s.stop:
|
case <-s.stop:
|
||||||
return fmt.Errorf("server is stopped")
|
return serverStopErr
|
||||||
}
|
|
||||||
w, err := s.Watch(p, true, false, index+1)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case v := <-w.EventChan:
|
case v := <-w.EventChan:
|
||||||
if v.Action == store.Set {
|
if v.Action == store.Set {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
index = v.Index()
|
log.Println("add error: action =", v.Action)
|
||||||
|
return tmpErr
|
||||||
case <-time.After(4 * defaultHeartbeat * s.tickDuration):
|
case <-time.After(4 * defaultHeartbeat * s.tickDuration):
|
||||||
|
w.Remove()
|
||||||
|
log.Println("add error: wait timeout")
|
||||||
|
return tmpErr
|
||||||
case <-s.stop:
|
case <-s.stop:
|
||||||
return fmt.Errorf("server is stopped")
|
w.Remove()
|
||||||
}
|
return serverStopErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +255,8 @@ func (s *Server) Remove(id int64) error {
|
|||||||
// removal target is self
|
// removal target is self
|
||||||
w, err := s.Watch(p, true, false, v.Index()+1)
|
w, err := s.Watch(p, true, false, v.Index()+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return removeTmpErr
|
log.Println("remove error:", err)
|
||||||
|
return tmpErr
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@ -257,10 +264,12 @@ func (s *Server) Remove(id int64) error {
|
|||||||
if v.Action == store.Delete {
|
if v.Action == store.Delete {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return removeTmpErr
|
log.Println("remove error: action =", v.Action)
|
||||||
|
return tmpErr
|
||||||
case <-time.After(4 * defaultHeartbeat * s.tickDuration):
|
case <-time.After(4 * defaultHeartbeat * s.tickDuration):
|
||||||
w.Remove()
|
w.Remove()
|
||||||
return removeTmpErr
|
log.Println("remove error: wait timeout")
|
||||||
|
return tmpErr
|
||||||
case <-s.stop:
|
case <-s.stop:
|
||||||
w.Remove()
|
w.Remove()
|
||||||
return serverStopErr
|
return serverStopErr
|
||||||
@ -284,18 +293,21 @@ func (s *Server) run() {
|
|||||||
|
|
||||||
func (s *Server) runParticipant() {
|
func (s *Server) runParticipant() {
|
||||||
node := s.node
|
node := s.node
|
||||||
addNodeC := s.addNodeC
|
|
||||||
removeNodeC := s.removeNodeC
|
|
||||||
recv := s.t.recv
|
recv := s.t.recv
|
||||||
ticker := time.NewTicker(s.tickDuration)
|
ticker := time.NewTicker(s.tickDuration)
|
||||||
v2SyncTicker := time.NewTicker(time.Millisecond * 500)
|
v2SyncTicker := time.NewTicker(time.Millisecond * 500)
|
||||||
|
|
||||||
var proposal chan v2Proposal
|
var proposal chan v2Proposal
|
||||||
|
var addNodeC, removeNodeC chan raft.Config
|
||||||
for {
|
for {
|
||||||
if node.HasLeader() {
|
if node.HasLeader() {
|
||||||
proposal = s.proposal
|
proposal = s.proposal
|
||||||
|
addNodeC = s.addNodeC
|
||||||
|
removeNodeC = s.removeNodeC
|
||||||
} else {
|
} else {
|
||||||
proposal = nil
|
proposal = nil
|
||||||
|
addNodeC = nil
|
||||||
|
removeNodeC = nil
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
case p := <-proposal:
|
case p := <-proposal:
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"runtime"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -101,31 +100,37 @@ func TestAdd(t *testing.T) {
|
|||||||
go es[0].Bootstrap()
|
go es[0].Bootstrap()
|
||||||
|
|
||||||
for i := 1; i < tt.size; i++ {
|
for i := 1; i < tt.size; i++ {
|
||||||
var index uint64
|
id := int64(i)
|
||||||
for {
|
for {
|
||||||
lead := es[0].node.Leader()
|
lead := es[0].node.Leader()
|
||||||
if lead != -1 {
|
if lead == -1 {
|
||||||
index = es[lead].Index()
|
time.Sleep(defaultElection * es[0].tickDuration)
|
||||||
ne := es[i]
|
continue
|
||||||
if err := es[lead].Add(ne.id, ne.raftPubAddr, ne.pubAddr); err == nil {
|
}
|
||||||
|
|
||||||
|
err := es[lead].Add(id, es[id].raftPubAddr, es[id].pubAddr)
|
||||||
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
switch err {
|
||||||
|
case tmpErr:
|
||||||
|
time.Sleep(defaultElection * es[0].tickDuration)
|
||||||
|
case serverStopErr:
|
||||||
|
t.Fatalf("#%d on %d: unexpected stop", i, lead)
|
||||||
|
default:
|
||||||
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
runtime.Gosched()
|
|
||||||
}
|
}
|
||||||
go es[i].run()
|
go es[i].run()
|
||||||
|
|
||||||
for j := 0; j <= i; j++ {
|
for j := 0; j <= i; j++ {
|
||||||
w, err := es[j].Watch(v2machineKVPrefix, true, false, index+1)
|
p := fmt.Sprintf("%s/%d", v2machineKVPrefix, id)
|
||||||
|
w, err := es[j].Watch(p, false, false, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("#%d on %d: %v", i, j, err)
|
t.Errorf("#%d on %d: %v", i, j, err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
v := <-w.EventChan
|
<-w.EventChan
|
||||||
ww := fmt.Sprintf("%s/%d", v2machineKVPrefix, i)
|
|
||||||
if v.Node.Key != ww {
|
|
||||||
t.Errorf("#%d on %d: path = %v, want %v", i, j, v.Node.Key, ww)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +174,7 @@ func TestRemove(t *testing.T) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch err {
|
switch err {
|
||||||
case removeTmpErr:
|
case tmpErr:
|
||||||
time.Sleep(defaultElection * 5 * time.Millisecond)
|
time.Sleep(defaultElection * 5 * time.Millisecond)
|
||||||
case serverStopErr:
|
case serverStopErr:
|
||||||
if lead == id {
|
if lead == id {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user