func (myRaft Raft) makeMockRafts() (Raft, *mock.MockCluster) { //create mock cluster. clconfig := cluster.Config{Peers: nil} cl, err := mock.NewCluster(clconfig) if err != nil { panic(err) } for id := 1; id <= PEERS; id++ { //Ojects to store statemachine, config and server node. myNode := new(RaftMachine) SM := new(sm.State_Machine) myConf := new(Config) //initialize config and server object. server := createMockNode(id, myConf, SM, cl) SM.Id = int32(id) myNode.Node = server myNode.SM = SM myNode.Conf = myConf //append object related to node into raft array. myRaft.Cluster = append(myRaft.Cluster, myNode) //start all the processing threads. go startNode(myRaft.Cluster[id-1].Conf, myRaft.Cluster[id-1].Node, myRaft.Cluster[id-1].SM) } return myRaft, cl }
func restoreData(SM *sm.State_Machine, myConf *Config) { //restore persistant state last := myConf.St.GetLastIndex() if last != -1 { state, err := myConf.St.Get(last) if err != nil { panic(err) } data := state.(sm.Persi_State) SM.Persi_State = data } //restore log last = myConf.Lg.GetLastIndex() if last != -1 { for i := int64(0); i <= last; i++ { log, err := myConf.St.Get(i) if err != nil { panic(err) } logg := log.(sm.MyLogg) SM.Logg.Logg[i] = logg } } SM.LoggInd = int32(last) }
func startNode(myConf *Config, server cluster.Server, SM *sm.State_Machine) { //Start backaground process to listen incomming packets from other servers. go processInbox(server, SM) //Start StateMachine in follower state. go SM.StartFollSys() //Raft node Processing. myConf.ProcessLock.Lock() processEvents(server, SM, myConf) myConf.ProcessLock.Unlock() }
func (myRaft Raft) makeRafts() Raft { for id := 1; id <= PEERS; id++ { myNode := new(RaftMachine) SM := new(sm.State_Machine) myConf := new(Config) server := createNode(id, myConf, SM) SM.Id = int32(id) myNode.Node = server myNode.SM = SM myNode.Conf = myConf myRaft.Cluster = append(myRaft.Cluster, myNode) go startNode(myRaft.Cluster[id-1].Conf, myRaft.Cluster[id-1].Node, myRaft.Cluster[id-1].SM) } return myRaft }
func StartRaft(myId int) *RaftMachine { myNode := new(RaftMachine) SM := new(sm.State_Machine) myConf := new(Config) //Start Node. server := createNode(myId, myConf, SM) SM.Id = int32(myId) //Restore previous test. restoreData(SM, myConf) myNode.SM = SM myNode.Conf = myConf myNode.Node = server go startNode(myConf, server, SM) return myNode }
func initNode(Id int, myConf *Config, SM *sm.State_Machine) { //Register a struct name by giving it a dummy object of that name. gob.Register(sm.AppEntrReq{}) gob.Register(sm.AppEntrResp{}) gob.Register(sm.VoteReq{}) gob.Register(sm.VoteResp{}) gob.Register(sm.StateStore{}) gob.Register(sm.LoggStore{}) gob.Register(sm.CommitInfo{}) gob.Register(sm.MyLogg{}) gob.Register(sm.Commit{}) gob.Register(sm.Append{}) gob.Register(sm.Persi_State{}) //Channel initialization. SM.CommMedium.ClientCh = make(chan interface{}, 10000) SM.CommMedium.NetCh = make(chan interface{}, 10000) SM.CommMedium.TimeoutCh = make(chan interface{}, 10000) SM.CommMedium.ActionCh = make(chan interface{}, 10000) SM.CommMedium.ShutdownCh = make(chan interface{}, 10000) SM.CommMedium.CommitInfoCh = make(chan interface{}, 10000) SM.CommMedium.CommitCh = make(chan interface{}, 10000) //Seed randon number generator. rand.Seed(time.Now().UTC().UnixNano() * int64(Id)) //Initialize the timer object for timeuts. myConf.DoTO = time.AfterFunc(10, func() {}) //Store persitant state myConf.DoStore = time.NewTicker(3 * time.Second) go func() { for _ = range myConf.DoStore.C { last := myConf.St.GetLastIndex() if last == -1 { err := myConf.St.Append(SM.Persi_State) if err != nil { panic(err) } err = myConf.St.Append(SM.Persi_State) if err != nil { panic(err) } } last = myConf.St.GetLastIndex() myConf.St.TruncateToEnd(last) err := myConf.St.Append(SM.Persi_State) if err != nil { panic(err) } last = myConf.St.GetLastIndex() state, err := myConf.St.Get(last) if err != nil { panic(err) } data := state.(sm.Persi_State) SM.Persi_State = data } }() //Initialize the Log and Node configuration. logConfig(Id, myConf) var err error myConf.Lg, err = log.Open(myConf.LogDir) if err != nil { panic(err) } myConf.St, err = log.Open(myConf.StDir) if err != nil { panic(err) } }