Beispiel #1
0
func (rn *RaftNode) Append(data []byte) {
	rn.smEventChan <- raftsm.CreateEvent("Append", "data", data)
}
Beispiel #2
0
func CreateRaftNode(conf Config) (*RaftNode, error) {
	rn := new(RaftNode)
	rn.id = conf.Id
	//rn.leaderId = 0    //? 0 is invalid
	rn.commitIndex = 0 //?verify
	rnlog, err := log.Open(conf.LogDir)
	if err != nil {
		return nil, err
	}
	rn.rnlog = rnlog
	rn.rnlog.RegisterSampleEntry(raftsm.LogEntry{})

	rn.server, err = GetServer(int(conf.Id), conf.Cluster)
	if err != nil {
		return nil, err
	}

	//--Init State Machine ---
	peerIds := make([]uint64, 0)
	for _, e := range conf.Cluster {
		if e.Id != conf.Id {
			peerIds = append(peerIds, e.Id)
		}
	}
	rn.majority = uint64(math.Ceil(float64(len(conf.Cluster)) / 2.0)) //? Assumes len is always odd
	rn.statefile = conf.LogDir + "/TermVotedFor"                      //? change required
	data, err := ioutil.ReadFile(rn.statefile)
	if err != nil {
		tvf := TermVotedFor{0, 0}
		data, err := json.Marshal(tvf)
		if err != nil {
			return nil, err
		}
		err = ioutil.WriteFile(rn.statefile, data, 0777)
		if err != nil {
			return nil, err
		}

		rn.currentTerm = 0
		rn.votedFor = 0
	} else {
		var tvf TermVotedFor
		err = json.Unmarshal(data, &tvf)
		if err != nil {
			return nil, err
		}
		rn.currentTerm = tvf.CurrentTerm
		rn.votedFor = tvf.VotedFor
	}

	rn.logIndex = uint64(rn.rnlog.GetLastIndex())
	le := make([]raftsm.LogEntry, 1) //? initilize from Log
	le[0] = raftsm.LogEntry{0, nil, false}

	if rn.rnlog.GetLastIndex() != int64(-1) {
		for i := uint64(0); i <= rn.logIndex; i++ {
			tmp, err := rn.rnlog.Get(int64(i))
			if err == nil {
				le = append(le, tmp.(raftsm.LogEntry))
			} else {
				return nil, err
			}
		}
	}
	rn.sm = raftsm.InitStateMachine(conf.Id, peerIds, rn.majority, time.Duration(conf.ElectionTimeout)*time.Millisecond, time.Duration(conf.HeartbeatTimeout)*time.Millisecond, rn.currentTerm, rn.votedFor /*//?*/, le)

	rn.smActionChan = *rn.sm.GetActionChannel()
	rn.smEventChan = *rn.sm.GetEventChannel()
	rn.commitChan = make(chan CommitInfo, 100)

	rn.timer = time.AfterFunc(100000*time.Second, func() {
		rn.smEventChan <- raftsm.CreateEvent("Timeout")
	})
	rn.timer.Stop()
	gob.Register(raftsm.Event{})
	return rn, nil
}