func (rn *RaftNode) Append(data []byte) { rn.smEventChan <- raftsm.CreateEvent("Append", "data", data) }
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 }