I am new in this group. I am trying to study Raft in etcd and have a question about the voting implementation.
In the current implementation, after a server is restarted, it can not be elected to be leader anymore as it is not "promotable".
By checking the source code, I found it may be solved by creating a snapshot which will restore the peers' progress.
The following test will get stuck as no server can be voted as a leader at the end. (I run this test by adding it to /coreos/etcd/raft/rafttest/node_test.go)
func Test(t *testing.T) {
peers := []raft.Peer{{1, nil}, {2, nil}, {3, nil}}
nt := newRaftNetwork(1, 2, 3)
nodes := make([]*node, 0)
for i := 1; i <= 3; i++ {
n := startNode(uint64(i), peers, nt.nodeNetwork(uint64(i)))
nodes = append(nodes, n)
}
waitLeader(nodes)
nodes[0].stop()
time.Sleep(time.Millisecond)
nodes[0].restart()
if nodes[0].Status().SoftState.Lead == 0 {
time.Sleep(time.Millisecond)
}
nodes[1].stop()
time.Sleep(time.Millisecond)
nodes[1].restart()
if nodes[1].Status().SoftState.Lead == 0 {
time.Sleep(time.Millisecond)
}
nodes[2].stop()
time.Sleep(time.Millisecond)
nodes[2].restart()
if nodes[2].Status().SoftState.Lead == 0 {
time.Sleep(time.Millisecond)
}
nodes[0].Propose(context.TODO(), []byte("somedata"))
if !waitCommitConverge(nodes, 1) {
t.Errorf("commits failed to converge!")
}
for _, n := range nodes {
n.stop()
}
}