func NewStateMachine(servers int64, id int64, actionCh chan events, electionTimeout int, lg *log.Log) *StateMachine { var sm *StateMachine = new(StateMachine) sm.servers = servers sm.id = id sm.status = "Follower" currentTerm, _ := leveldb.OpenFile("currentTerm", nil) defer currentTerm.Close() // Database to store votedFor voted, _ := leveldb.OpenFile("votedFor", nil) defer voted.Close() //sm.currentTerm = currentTerm //defer sm.currentTerm.Close() Term, err := currentTerm.Get([]byte(strconv.FormatInt(sm.id, 10)), nil) if err == nil { sm.Term, _ = strconv.ParseInt(string(Term), 10, 64) } else { sm.Term = int64(0) } //sm.voted = voted //defer sm.voted.Close() vote, err := voted.Get([]byte(strconv.FormatInt(sm.id, 10)), nil) if err == nil { sm.votedFor, _ = strconv.ParseInt(string(vote), 10, 64) } else { sm.votedFor = int64(-1) } sm.log = make([][]byte, 10000000) sm.logTerm = make(map[int64]int64) size := lg.GetLastIndex() + 1 if size == 0 { sm.LastLogIndex = -1 sm.LastLogTerm = 0 } else { for i := int64(0); i < size; i++ { b, _ := lg.Get(i) var entry LogInfo json.Unmarshal(b.([]byte), &entry) sm.log[i] = entry.Data sm.logTerm[i] = entry.Term } sm.LastLogIndex = size - 1 sm.LastLogTerm = sm.logTerm[size-1] } sm.commitIndex = -1 sm.actionCh = actionCh sm.electionTimeout = time.Millisecond * time.Duration(electionTimeout) sm.votesMap = make(map[int64]int) sm.nextIndex = make(map[int64]int64) sm.matchIndex = make(map[int64]int64) //sm.acksRecieved = make(map[int64]int64) return sm }
func NewStateMachine(id int, peerIds []int, electionTimeout float64, heartbeatTimeout float64, lg *log.Log) *StateMachine { sm := StateMachine{ ServerID: id, State: "follower", VoteGranted: make(map[int]bool), NextIndex: make(map[int]int), MatchIndex: make(map[int]int), updateCh: make(chan interface{}, 250000), netCh: make(chan interface{}, 250000), actionCh: make(chan interface{}, 250000), LastLogIndex: -1, CommitIndex: -1, PeerIds: peerIds, Log: make([]LogEntry, 0), //see } sm.ELECTION_TIMEOUT = electionTimeout sm.HEARTBEAT_TIMEOUT = heartbeatTimeout NUMBER_OF_NODES = len(peerIds) CurrentTermDB, _ := leveldb.OpenFile(PATH+"/currentTerm", nil) defer CurrentTermDB.Close() termStr, err := CurrentTermDB.Get([]byte(strconv.FormatInt(int64(sm.ServerID), 10)), nil) if err == nil { sm.CurrentTerm, _ = strconv.Atoi(string(termStr)) } else { sm.CurrentTerm = int(0) } VotedForDB, _ := leveldb.OpenFile(PATH+"/votedFor", nil) defer VotedForDB.Close() votedForStr, err := VotedForDB.Get([]byte(strconv.Itoa(sm.ServerID)), nil) if err == nil { sm.VotedFor, _ = strconv.Atoi(string(votedForStr)) } else { sm.VotedFor = int(0) } lastIndex := int(lg.GetLastIndex()) //fmt.Println("last index is ", lastIndex) if lastIndex != -1 { var i int for i = 0; i <= lastIndex; i++ { b, _ := lg.Get(int64(i)) //see // entry := b.([]byte).(LogEntry) var entry LogEntry json.Unmarshal(b.([]byte), &entry) sm.Log = append(sm.Log, entry) //see } sm.LastLogIndex = lastIndex sm.LastLogTerm = sm.getLogTerm(lastIndex) } return &sm }