Skip to content
Snippets Groups Projects
Commit 3a439b43 authored by djq2's avatar djq2
Browse files

noway

parent ef3f0a38
Branches please
No related tags found
No related merge requests found
...@@ -70,6 +70,8 @@ type Raft struct { ...@@ -70,6 +70,8 @@ type Raft struct {
// For Leaders Only - Metadata on Followers // For Leaders Only - Metadata on Followers
nextIndex[] int // Index of next log entry to send to server <i> nextIndex[] int // Index of next log entry to send to server <i>
matchIndex[] int // Index of highest log entry known to be replicated on server <i> matchIndex[] int // Index of highest log entry known to be replicated on server <i>
tempConflict int
} }
type ballot struct { type ballot struct {
...@@ -109,6 +111,9 @@ type AppendEntriesReply struct { ...@@ -109,6 +111,9 @@ type AppendEntriesReply struct {
// Your data here (2A). // Your data here (2A).
Term int // Client's current term if leader needs to update itself Term int // Client's current term if leader needs to update itself
Success bool // True if follower contained entries that matched PrevLogIndex and PrevLogTerm Success bool // True if follower contained entries that matched PrevLogIndex and PrevLogTerm
ConflictIdx int
ConflictTerm int
} }
...@@ -121,41 +126,36 @@ func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) { ...@@ -121,41 +126,36 @@ func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) {
// Refresh timeout // Refresh timeout
rf.mu.Lock() rf.mu.Lock()
rf.startTime = time.Now()
// fmt.Printf("Vote from %d to %d \n", args.CandidateID, rf.me) // fmt.Printf("Vote from %d to %d \n", args.CandidateID, rf.me)
// fmt.Printf("voted for term %d vote term %d\n", rf.votedFor.term, args.Term) // fmt.Printf("voted for term %d vote term %d\n", rf.votedFor.term, args.Term)
// rf.printLog() // rf.printLog()
if rf.currentTerm > args.Term{ if rf.currentTerm > args.Term || (rf.currentTerm == args.Term && len(rf.log) - 1 > args.LastLogIndex) || rf.votedFor.term > args.Term {
reply.Term = rf.currentTerm
reply.VoteGranted = false
reply.Responded = true
} else if rf.votedFor.term > args.Term{
reply.Term = rf.currentTerm reply.Term = rf.currentTerm
reply.VoteGranted = false reply.VoteGranted = false
reply.Responded = true reply.Responded = true
} else if ((rf.votedFor.term == args.Term && rf.votedFor.candidate == -1) || (rf.votedFor.term == args.Term && rf.votedFor.candidate == args.CandidateID)) && (len(rf.log) == 0 || (args.LastLogIndex >= len(rf.log) - 1 && args.LastLogTerm == rf.log[len(rf.log) - 1].Term)){ rf.mu.Unlock()
rf.startTime = time.Now() return
} else if ( (rf.votedFor.term == args.Term && rf.votedFor.candidate == -1) || (rf.votedFor.term == args.Term && rf.votedFor.candidate == args.CandidateID)) && (len(rf.log) == 0 || (args.LastLogIndex >= len(rf.log) - 1 && args.LastLogTerm == rf.log[len(rf.log) - 1].Term)){
reply.Term = rf.currentTerm reply.Term = rf.currentTerm
reply.VoteGranted = true reply.VoteGranted = true
reply.Responded = true reply.Responded = true
rf.votedFor.candidate = args.CandidateID rf.votedFor.candidate = args.CandidateID
rf.state = "FOLLOWER"
// fmt.Print("id: " + strconv.Itoa(rf.me) + " term: " + strconv.Itoa(rf.currentTerm)) // fmt.Print("id: " + strconv.Itoa(rf.me) + " term: " + strconv.Itoa(rf.currentTerm))
// fmt.Print(" ") // fmt.Print(" ")
// fmt.Print(rf.state) // fmt.Print(rf.state)
// fmt.Print(" Vote Term: " + strconv.Itoa(rf.votedFor.term) + " Voted For: " + strconv.Itoa(rf.votedFor.candidate)) // fmt.Print(" Vote Term: " + strconv.Itoa(rf.votedFor.term) + " Voted For: " + strconv.Itoa(rf.votedFor.candidate))
// fmt.Print("\n") // fmt.Print("\n")
} else if rf.votedFor.term < args.Term && (len(rf.log) == 0 || (args.LastLogIndex >= len(rf.log) - 1 && args.LastLogTerm == rf.log[len(rf.log) - 1].Term)){ } else if rf.votedFor.term < args.Term && (len(rf.log) == 0 || args.LastLogTerm > rf.log[len(rf.log) - 1].Term || (args.LastLogIndex >= len(rf.log) - 1 && args.LastLogTerm >= rf.log[len(rf.log) - 1].Term)){
rf.startTime = time.Now()
reply.Term = rf.currentTerm reply.Term = rf.currentTerm
reply.VoteGranted = true reply.VoteGranted = true
reply.Responded = true reply.Responded = true
rf.votedFor.candidate = args.CandidateID rf.votedFor.candidate = args.CandidateID
rf.votedFor.term = args.Term rf.votedFor.term = args.Term
rf.state = "FOLLOWER"
//print("here") //print("here")
// fmt.Print("id: " + strconv.Itoa(rf.me) + " term: " + strconv.Itoa(rf.currentTerm)) // fmt.Print("id: " + strconv.Itoa(rf.me) + " term: " + strconv.Itoa(rf.currentTerm))
// fmt.Print(" ") // fmt.Print(" ")
...@@ -164,7 +164,6 @@ func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) { ...@@ -164,7 +164,6 @@ func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) {
// fmt.Print("\n") // fmt.Print("\n")
} else { } else {
reply.Term = rf.currentTerm reply.Term = rf.currentTerm
reply.VoteGranted = false reply.VoteGranted = false
reply.Responded = true reply.Responded = true
...@@ -189,6 +188,7 @@ func (rf *Raft) AppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply ...@@ -189,6 +188,7 @@ func (rf *Raft) AppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply
if rf.state == "LEADER" && args.Term > rf.currentTerm{ if rf.state == "LEADER" && args.Term > rf.currentTerm{
rf.state = "FOLLOWER" rf.state = "FOLLOWER"
} }
if rf.currentTerm > args.Term && rf.commitIndex >= args.LeaderCommit { if rf.currentTerm > args.Term && rf.commitIndex >= args.LeaderCommit {
//this might be wrong && might be wrong //this might be wrong && might be wrong
...@@ -248,6 +248,19 @@ func (rf *Raft) AppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply ...@@ -248,6 +248,19 @@ func (rf *Raft) AppendEntries(args *AppendEntriesArgs, reply *AppendEntriesReply
} else { } else {
//add else statment later to handle optimization //add else statment later to handle optimization
reply.Success = false reply.Success = false
if args.PrevLogIndex >= len(rf.log) {
reply.ConflictIdx = len(rf.log) - 1
reply.ConflictTerm = -1
} else {
wrongTerm := rf.log[args.PrevLogIndex].Term
reply.ConflictTerm = wrongTerm
for i := 0; i < len(rf.log); i++ {
if rf.log[i].Term == reply.ConflictTerm{
reply.ConflictIdx = i
break
}
}
}
} }
reply.Term = rf.currentTerm reply.Term = rf.currentTerm
...@@ -292,6 +305,7 @@ func (rf *Raft) handleCommitChannel(){ ...@@ -292,6 +305,7 @@ func (rf *Raft) handleCommitChannel(){
// rf.mu.Lock() // rf.mu.Lock()
// fmt.Println("Server " + strconv.Itoa(rf.me) + ", " + rf.state + ": ") // fmt.Println("Server " + strconv.Itoa(rf.me) + ", " + rf.state + ": ")
// fmt.Println()
// fmt.Print("Full Log: ") // fmt.Print("Full Log: ")
// fmt.Println(rf.log) // fmt.Println(rf.log)
// fmt.Println() // fmt.Println()
...@@ -515,7 +529,7 @@ func (rf *Raft) Leader() { ...@@ -515,7 +529,7 @@ func (rf *Raft) Leader() {
// print(rf.me) // print(rf.me)
// print("\n") // print("\n")
// fmt.Print(strconv.Itoa(rf.me) + "is new leader \n") fmt.Print(strconv.Itoa(rf.me) + "is new leader \n")
heartbeat := time.Duration(100) * time.Millisecond heartbeat := time.Duration(100) * time.Millisecond
//send heartbeat to take tell others you are leader //send heartbeat to take tell others you are leader
rf.mu.Lock() rf.mu.Lock()
...@@ -661,8 +675,21 @@ func (rf *Raft) sendHeartbeat(){ ...@@ -661,8 +675,21 @@ func (rf *Raft) sendHeartbeat(){
rf.commitReadyChan <- struct{}{} rf.commitReadyChan <- struct{}{}
} }
} else { } else {
if rf.nextIndex[id] > 0{ if resp.ConflictTerm >= 0 {
rf.nextIndex[id] = rf.nextIndex[id] -1 lastValid := -1
for i := len(rf.log) - 1; i >= 0; i-- {
if rf.log[i].Term == resp.ConflictTerm {
lastValid = i
break
}
}
if lastValid >= 0 {
rf.nextIndex[id] = lastValid + 1
} else {
rf.nextIndex[id] = resp.ConflictIdx
}
} else {
rf.nextIndex[id] = resp.ConflictIdx
} }
} }
......
...@@ -347,7 +347,6 @@ func TestRejoin2B(t *testing.T) { ...@@ -347,7 +347,6 @@ func TestRejoin2B(t *testing.T) {
cfg.rafts[leader1].Start(103) cfg.rafts[leader1].Start(103)
cfg.rafts[leader1].Start(104) cfg.rafts[leader1].Start(104)
// new leader commits, also for index=2 // new leader commits, also for index=2
cfg.one(103, 2, true) cfg.one(103, 2, true)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment