Example #1
0
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
}
Example #2
0
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
}