diff --git a/src/raft/.gitignore b/src/raft/.gitignore new file mode 100644 index 0000000..6d9594a --- /dev/null +++ b/src/raft/.gitignore @@ -0,0 +1 @@ +/logs/ diff --git a/src/raft/raft.go b/src/raft/raft.go index bbbb17f..01e7ef3 100644 --- a/src/raft/raft.go +++ b/src/raft/raft.go @@ -48,6 +48,12 @@ type Raft struct { matchCommandIds []int // for each server, index of highest log entry known to be replicated on server (initialized to 0, increases monotonically) } +func (rf *Raft) printAllLogs(fnName string) { + for _, entry := range rf.log { + DPrintf("[%s.%d.%d] Command[%d|%d] %d", fnName, rf.currentTerm, rf.me, entry.CommandIndex, entry.Term, entry.Command) + } +} + func (rf *Raft) getLastLogEntry() (*ApplyMsg, error) { // rf.mu.Lock() // defer rf.mu.Unlock() @@ -196,6 +202,7 @@ func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) { // If the logs have last entries with different terms, then the log with the later term is more up-to-date. if lastLogTerm > args.PrevLogTerm { + rf.printAllLogs("VoteNo") DPrintf("%d Voting no because my last entry has higher term %d, candiate PrevLogTerm %d", rf.me, lastLogTerm, args.PrevLogTerm) reply.VoteNo(lastLogTerm) return @@ -206,6 +213,7 @@ func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) { // If the logs end with the same term, then whichever log is longer is more up-to-date if lastLogTerm == args.PrevLogTerm { if lastLogCommandID > args.PrevCommandID { + rf.printAllLogs("VoteNo") DPrintf("%d Voting no because my log lastCommandID is larger %d, candidate PrevCommandID %d", rf.me, lastLogCommandID, args.PrevCommandID) reply.VoteNo(lastLogTerm) return @@ -246,6 +254,7 @@ type RequestAppendEntriesReply struct { } func (rf *Raft) denyAppendEntry(args *RequestAppendEntriesArgs, reply *RequestAppendEntriesReply){ + rf.printAllLogs("denyAppendEntry") reply.Success = false reply.Term = rf.currentTerm reply.LastLogIndex = rf.commitCommandID @@ -341,13 +350,14 @@ func (rf *Raft) sendAppendEntries( } if !reply.Success { - rf.decrementNextIndex(server, reply) - rf.mu.Lock() - defer rf.mu.Unlock() if reply.Term > rf.currentTerm { + rf.mu.Lock() + defer rf.mu.Unlock() rf.currentTerm = reply.Term rf.role = Follower rf.persist() + } else { + rf.decrementNextIndex(server, reply) } return } @@ -449,7 +459,7 @@ func (rf *Raft) AppendEntries( defer rf.mu.Unlock() // 1. Reply false if term < currentTerm (ยง5.1) if rf.currentTerm > args.Term { - DPrintf("%d Not accepting log due to low term", rf.me) + DPrintf("%d Not accepting log due to low term %d myTerm=%d", rf.me, args.Term, rf.currentTerm) rf.denyAppendEntry(args, reply) return } diff --git a/src/raft/tester.sh b/src/raft/tester.sh new file mode 100755 index 0000000..68cd87d --- /dev/null +++ b/src/raft/tester.sh @@ -0,0 +1,7 @@ +#!/bin/bash +for i in {1..50} +do + # go test -run Figure8Unreliable2C + # go test -run Figure82C + go test -run Backup2B +done diff --git a/src/raft/util.go b/src/raft/util.go index ec71d81..ff3f8c3 100644 --- a/src/raft/util.go +++ b/src/raft/util.go @@ -1,14 +1,39 @@ package raft -import "log" +import ( + "fmt" + "log" + "os" + "time" +) // Debugging const Debug = false +var file *os.File + +func EnableLogger() { + if file == nil { + curPath, _ := os.Getwd() + filePath := curPath + "/logs/" + time.Now().Format("2006-01-02") + "." + time.Now().Format("15:04") + ".logger" + file, _ = os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + } +} + +func Write(str string) { + _, err := file.WriteString(str) + if err != nil { + panic(err) + } +} + func DPrintf(format string, a ...interface{}) (n int, err error) { + EnableLogger() + msg := fmt.Sprintf(format, a...) if Debug { - log.Printf(format, a...) + log.Println(msg) } + Write(msg) return }