func New(rnConfig RaftNodeConfig, jsonFile string) RaftNode { var rn RaftNode rn.eventCh = make(chan interface{}, 100) //rn.timeoutCh = make(chan bool) rn.shutdownSig = make(chan bool) rn.commitCh = make(chan CommitInfo, 100) // rn.parTOs = 0 rn.logDir = rnConfig.logDir rn.initializeStateMachine(rnConfig) var err error rn.nwHandler, err = cluster.New(int(rnConfig.id), jsonFile) assert(err == nil) // Register various types to be send on outbox and receive in inbox gob.Register(VoteReqEv{}) gob.Register(VoteResEv{}) gob.Register(AppendEntriesReqEv{}) gob.Register(AppendEntriesResEv{}) // Set initial election timeout /*go func() { time.Sleep(time.Millisecond * time.Duration(RandInt(rn.sm.electionTO))) rn.timeoutCh <- true }()*/ rn.timer = time.NewTimer(time.Duration(RandInt(rnConfig.electionTO)) * time.Millisecond) return rn }
func NewRN(state State, id int, clusterConfigFileName string, logFileName string, hbTimeout int, timeout int) (*RaftNode, error) { //TODO Add code for recovery registerStructs() srvr, err := cluster.New(id, clusterConfigFileName) if err != nil { return nil, err } _mainLog, err := log.Open(logFileName) if err != nil { return nil, err } _stateLog, err := log.Open(logFileName + "_state") if err != nil { return nil, err } _mainLog.RegisterSampleEntry([]byte{}) _stateLog.RegisterSampleEntry(StateInfo{}) _sm, alarm := NewSm(state, id, srvr.Peers(), hbTimeout, timeout) rn := RaftNode{appendCh: make(chan Event, 1000), commitCh: make(chan *CommitInfo, 1000), processQuitCh: make(chan bool, 1), isOn: true, sm: _sm, server: srvr, mainLog: _mainLog, stateLog: _stateLog} rn.timer = time.NewTimer(time.Millisecond * time.Duration(alarm.duration)) go rn.handleEvent() return &rn, err }
func GetServer(id int, Cluster []NetConfig) (cluster.Server, error) { peers := make([]cluster.PeerConfig, len(Cluster)) for i, e := range Cluster { peers[i] = cluster.PeerConfig{Id: int(e.Id), Address: e.Host + ":" + strconv.Itoa(int(e.Port))} } cnf := cluster.Config{Peers: peers} return cluster.New(id, cnf) }
// Generates a cluster of 5 raft nodes with associated tcp ports func makeRafts() []RaftNode { var r []RaftNode for i := 0; i < len(configs.Peers); i++ { config := NodeConfig{configs, i, "$GOPATH/src/github.com/aakashdeshpande/cs733/assignment3/", 500} r = append(r, New(config)) r[i].server, _ = cluster.New(i, configs) } return r }
//Craetes node, statemachine & Initializes the node. func createNode(id int, myConf *Config, sm *State_Machine) cluster.Server { initNode(id, myConf, sm) //Set up details about cluster nodes form json file. server, err := cluster.New(id, "config/cluster_config.json") if err != nil { panic(err) } return server }
func New(nodeConfig Config) (Node, error) { clusterConfig := cluster.Config{Peers: NetToPeersConfig(nodeConfig.cluster), InboxSize: 50, OutboxSize: 50} server, err := cluster.New(nodeConfig.Id, clusterConfig) if err != nil { return nil, errors.New("Could not start the messaging service") } lg, err := log.Open(nodeConfig.LogDir) if err != nil { return nil, errors.New("Could not start log service") } lg.RegisterSampleEntry(LogEntry{}) commitChannel := make(chan CommitInfo) eventChannel := make(chan interface{}) shutdownChan := make(chan int) initLog := make([]LogEntry, 0) initLog = append(initLog, LogEntry{0, make([]byte, 0)}) votedFor := -1 term := 0 _, err = os.Stat(strconv.Itoa(nodeConfig.Id) + "_state") if err == nil { // State file already exists, so restart read vars from it term, votedFor = readState(nodeConfig.Id) // restore log entries from log saved on disk logLastIndex := lg.GetLastIndex() if logLastIndex != -1 { //logger.Println(nodeConfig.Id, " : Last index on disk : ", logLastIndex) for i := 0; int64(i) < logLastIndex; i++ { entry, _ := lg.Get(int64(i)) initLog = append(initLog, entry.(LogEntry)) } } } sm := StateMachine{nodeConfig.Id, getPeers(nodeConfig.cluster), term, votedFor, 1, initLog, make(map[int]int), make(map[int]int), 0, nodeConfig.ElectionTimeout, make(map[int]int), -1} rn := RaftNode{sm: sm, server: server, lg: lg, commitChannel: commitChannel, eventChannel: eventChannel, shutDownChan: shutdownChan} timerFunc := func(eventChannel chan interface{}) func() { return func() { rn.eventChannel <- TimeoutEv{} } } rn.timer = time.AfterFunc(time.Duration(random(sm.timeout, 2*sm.timeout))*time.Millisecond, timerFunc(rn.eventChannel)) rn.commitLock = &sync.RWMutex{} gob.Register(AppendEntriesReqEv{}) gob.Register(AppendEntriesRespEv{}) gob.Register(VoteReqEv{}) gob.Register(VoteRespEv{}) go rn.ProcessEvents() return &rn, nil }
func makeRafts() []RaftNode { // votedForDB, _ = leveldb.OpenFile(PATH+"/votedFor", nil) var nodes []RaftNode for i := 0; i < len(configs.Peers); i++ { config := Config{configs, configs.Peers[i].Id, PATH + "", 550, 50} server, _ := cluster.New(configs.Peers[i].Id, configs) nodes = append(nodes, New(config, server)) } return nodes }
// Generates a cluster of 5 raft nodes with associated tcp ports func makeRafts() []RaftNode { var r []RaftNode r = make([]RaftNode, len(configs.Peers)) for i := 0; i < len(configs.Peers); i++ { config := NodeConfig{configs, i, "Logs/", 500} r[i] = New(config) r[i].server, _ = cluster.New(i, configs) } return r }
// makerafts function will make 5 rodeNodes .It will associate a stateMAchine to all nodes. func makerafts() []*RaftNode { raftset := make([]*RaftNode, 5) for i := 0; i < 5; i++ { raft, err := cluster.New(i, "peer.json") checkError(err) node := initialize(raft, i) raftset[i] = node } return raftset }
func New(conf Config) Node { var ( rn RaftNode rsmLog []LogEntry peerIds []int hasVoted map[int]int nextIndex map[int]int64 matchIndex map[int]int64 ClustConfig cluster.Config ) // initlisation of other raft node variables rn.IsWorking = true rn.TimeoutTimer = time.NewTimer(time.Duration(randRange(conf.ElectionTimeout, 2*conf.ElectionTimeout)) * time.Millisecond) <-rn.TimeoutTimer.C //fmt.Println(<-rn.TimeoutTimer.C) rn.AppendEventCh = make(chan Event, 100) //rn.TimeoutEventCh = make(chan Event, 100) rn.CommitCh = make(chan CommitInfo, 100) ClustConfig = GetClusterConfig(conf) rn.NetServer, _ = cluster.New(conf.Id, ClustConfig) rn.LogFile, _ = log.Open(conf.LogFileDir) // initilisation of state machine peerIds = getPeerIds(conf) hasVoted = getVotesRcvd(peerIds) nextIndex = getNextIndex(peerIds) matchIndex = getMatchIndex(peerIds) registerStructs() rsmLog, _ = rn.getRsmLog() //rsmState, err = rn.getRsmState(); rn.SM.init( /* currTerm */ 0, /* votedFor */ -1, /* Log */ rsmLog, /* selfId */ conf.Id, /* peerIds */ peerIds, /* electionAlarm */ conf.ElectionTimeout, /* heartbeatAlarm */ conf.HeartbeatTimeout, /* lastMatchIndex */ -1, /* currState --Follower*/ "follower", /* commitIndex */ -1, /* leaderId */ -1, /* lastLogIndex */ -1, /* lastLogTerm */ 0, /* votedAs */ hasVoted, /* nextIndex */ nextIndex, /* matchIndex */ matchIndex) go rn.ProcessNodeEvents() return &rn }
func New(RaftNode_config RaftConfig) RaftNode { //make raftnode object and set it var rn RaftNode rn.rc = RaftNode_config rn.sm = InitializeStateMachine(RaftNode_config) rn.EventCh = make(chan interface{}, 1000) rn.CommitCh = make(chan CommitInfo, 1000) rn.timer = time.NewTimer(time.Duration(RaftNode_config.ElectionTimeout) * time.Millisecond) rn.quit = make(chan bool) rn.srvr, _ = cluster.New(RaftNode_config.Id, "Config.json") //make server object for communication // register events gob.Register(VoteRequestEvent{}) gob.Register(VoteResponseEvent{}) gob.Register(AppendEntriesRequestEvent{}) gob.Register(AppendEntriesResponseEvent{}) return rn }
func NewFsNode(state State, id int, clusterConfigFileName string, logFileName string, hbTimeout int, timeout int, _pubaddr string) (*FsNode, error) { //TODO Add code for recovery registerStructs() srvr, err := cluster.New(id, clusterConfigFileName) if err != nil { return nil, err } _mainLog, err := log.Open(logFileName) if err != nil { return nil, err } _stateLog, err := log.Open(logFileName + "_state") if err != nil { return nil, err } _mainLog.RegisterSampleEntry([]byte{}) _stateLog.RegisterSampleEntry(StateInfo{}) _sm, alarm := NewSm(state, id, srvr.Peers(), hbTimeout, timeout) fsn := FsNode{appendCh: make(chan Event, 1000), commitCh: make(chan *CommitInfo, 1000), processQuitCh: make(chan bool, 1), frontEndQuitCh: make(chan bool, 1), backEndQuitCh: make(chan bool, 1), isOn: true, sm: _sm, server: srvr, mainLog: _mainLog, stateLog: _stateLog, dict: make(map[string]*FileStruct, 1000), pubaddr: _pubaddr, connMap: make(map[int64]*net.Conn)} fsn.timer = time.NewTimer(time.Millisecond * time.Duration(alarm.duration)) addr, err := net.ResolveTCPAddr("tcp4", fsn.pubaddr) printErr(err) fsn.socket, err = net.ListenTCP("tcp", addr) printErr(err) go fsn.frontEndMain() go fsn.backEndMain() go fsn.handleEvent() return &fsn, err }
func main() { var configs []raftnode.Config tmp_cnfg, _ := ioutil.ReadFile("configs.json") err := json.Unmarshal(tmp_cnfg, &configs) check(err) // var cluster_config cluster.Config // tmp_clusterConfig,_ := ioutil.ReadFile("clusterconfig.json") // err = json.Unmarshal(tmp_clusterConfig,&cluster_config) // check(err) id, err1 := strconv.Atoi(os.Args[1]) check(err1) // server, err := cluster.New(id, "cluster_test_config.json") //fmt.Println("port: ",configs[id-1].Cluster[id-1].Port,id) //ioutil.WriteFile("welcome.txt",[]byte(s),0644) serverMain(id, (configs[id-1]), server) //serverMain(1,configs[0],mck) }
func New(config Config, jsonFile string) (rnode RaftNode) { rnode.sm.serverId = config.Id //fmt.Printf("In New k value: %v\n", len(config.cluster)-1) rnode.sm.peerIds = make([]int64, len(config.cluster)-1, len(config.cluster)-1) k := 0 for _, peer := range config.cluster { //fmt.Printf("In New k value: %d\n", k) if peer.Id != config.Id { rnode.sm.peerIds[k] = peer.Id k++ } } rnode.sm.majority = int64(math.Ceil(float64(len(config.cluster)) / 2.0)) rnode.sm.commitIndex = -1 rnode.logfile = config.LogDir + "/" + "logfile" lg, err := log.Open(rnode.logfile) lg.RegisterSampleEntry(logEntry{}) assert(err == nil) defer lg.Close() if lg.GetLastIndex() == -1 { rnode.sm.log = []logEntry{} } else { i := lg.GetLastIndex() for j := int64(0); j <= i; j++ { data, _ := lg.Get(j) rnode.sm.log = append(rnode.sm.log, data.(logEntry)) } } rnode.sm.nextIndex = make([]int64, len(config.cluster)-1, len(config.cluster)-1) for n := 0; n < len(config.cluster)-1; n++ { rnode.sm.nextIndex[n] = int64(len(rnode.sm.log)) } rnode.sm.matchIndex = make([]int64, len(config.cluster)-1, len(config.cluster)-1) for m := 0; m < len(config.cluster)-1; m++ { rnode.sm.matchIndex[m] = -1 } rnode.statefile = config.LogDir + "/" + "statefile" currstate, err := log.Open(rnode.statefile) currstate.RegisterSampleEntry(NodePers{}) assert(err == nil) defer currstate.Close() if currstate.GetLastIndex() == -1 { rnode.sm.currentTerm = int64(0) rnode.sm.currentState = "follower" } else { i := currstate.GetLastIndex() h, _ := currstate.Get(i) rnode.sm.currentTerm = h.(NodePers).CurrentTerm rnode.sm.currentState = h.(NodePers).CurrentState rnode.sm.votedFor = h.(NodePers).VotedFor } rnode.sm.totalvotes = int64(0) rnode.sm.novotes = int64(0) rnode.eventch = make(chan interface{}, 1000) rnode.commitch = make(chan CommitInfo, 1000) rnode.endch = make(chan bool) //rnode.timeoutch = make(chan TimeoutEv) //rnode.resettimer = 0 rnode.sm.ElectionTimeout = config.ElectionTimeout rnode.sm.HeartbeatTimeout = config.HeartbeatTimeout gob.Register(AppendEv{}) gob.Register(AppendEntriesReqEv{}) gob.Register(AppendEntriesRespEv{}) gob.Register(TimeoutEv{}) gob.Register(VoteReqEv{}) gob.Register(VoteRespEv{}) rnode.timer = time.NewTimer(time.Duration(config.ElectionTimeout) * time.Millisecond) var err3 error rnode.sm_messaging, err3 = cluster.New(int(config.Id), jsonFile) if err3 != nil { fmt.Printf("Error in sm_messaging.") } return }
func New(config Config) *RaftNode { Register() var raft RaftNode directories := config.LogDir + strconv.Itoa(config.Id) lg, _ := log.Open(directories) lastindex := lg.GetLastIndex() intlastindex := int(lastindex) mypeers := make([]int, noOfServers) myLog := make([]Log, 0) myLog = append(myLog, Log{0, []byte("hello")}) mynextIndex := make([]int, noOfServers) mymatchIndex := make([]int, noOfServers) myVoteReceived := make([]int, noOfServers) statestore := "statestore" + strconv.Itoa(config.Id) file, e := ioutil.ReadFile("./" + statestore) if e != nil { fmt.Printf("File error: %v\n", e) os.Exit(1) } var jsontype JsonStateStore json.Unmarshal(file, &jsontype) var wait sync.WaitGroup raft.wg = &wait configCluster := cluster.Config{ Peers: []cluster.PeerConfig{}, InboxSize: config.InboxSize, OutboxSize: config.OutboxSize, } for i := 0; i < len(config.Cluster); i++ { configCluster.Peers = append(configCluster.Peers, cluster.PeerConfig{Id: config.Cluster[i].Id, Address: fmt.Sprint(config.Cluster[i].Host, ":", config.Cluster[i].Port)}) mypeers[i] = config.Cluster[i].Id } s := RaftStateMachine{ Term: jsontype.Term, VotedFor: jsontype.VotedFor, State: "follower", MyID: config.Id, PeerID: mypeers, Log: myLog, CommitIndex: 0, LeaderID: -1, NextIndex: mynextIndex, MatchIndex: mymatchIndex, VoteReceived: myVoteReceived, HeartbeatTimeout: config.HeartbeatTimeout, ElectionTimeout: config.ElectionTimeout, } raft.server = s for i := 0; i <= intlastindex; i++ { newLog, _ := lg.Get(int64(i)) raft.server.Log = append(raft.server.Log, Log{Term: 0, Data: newLog}) } eventChannel := make(chan Event, 1000) commitChannel := make(chan *Commit, 1000) shutdownChannel := make(chan Event, 1000) raft.eventCh = eventChannel raft.commitCh = commitChannel raft.shutdownCh = shutdownChannel clusterServer, _ := cluster.New(config.Id, configCluster) raft.serverOfCluster = clusterServer raft.log = lg raft.LogDir = config.LogDir return &raft }
func New1(myid int, configuration interface{}) (n Node, err error) { Raft := new(RaftNode) n = Raft var config *Config var pdata []byte if config, err = ConfigRaft(configuration); err != nil { return nil, err } config.Id = myid pdata, err = ioutil.ReadFile(fmt.Sprintf("persistent_store_%d", myid)) if err != nil { panic(err) } p := strings.Split(string(pdata), " ") p[0] = strings.TrimSpace(p[0]) p[1] = strings.TrimSpace(p[1]) smterm, _ := strconv.Atoi(p[1]) smvotedfor, _ := strconv.Atoi(p[0]) server, err := cluster.New(myid, "cluster_test_config.json") if err != nil { panic(err) } Raft.srv = server Raft.config = config nodesid := [4]int{} j := 0 for i := 0; i <= 4; i++ { if config.Cluster[i].Id != myid { nodesid[j] = config.Cluster[i].Id j = j + 1 } } next := []int{1, 1, 1, 1, 1, 1} sm = &StateMachine{id: myid, term: smterm, LastLogIndex: 0, CommitIndex: 0, PrevLogIndex: -1, nextIndex: next, peers: nodesid, votedfor: smvotedfor, status: "Follower", LeaderID: 0, ElectionTimeout: config.ElectionTimeout, HeartBeatTimeout: config.HeartbeatTimeout} Raft.sm = sm rand.Seed(time.Now().UnixNano()) RandomNo := rand.Intn(500) Raft.Timer = time.AfterFunc(time.Duration(config.ElectionTimeout+RandomNo)*time.Millisecond, func() { Raft.timeoutCh <- TimeoutEv{} }) Raft.Heart_Beat_Timer = time.NewTicker(time.Duration(config.HeartbeatTimeout) * time.Millisecond) go Raft.processEvents() go Raft.sm.ProcessEvent(make([]interface{}, 1)) Events := make(chan Event, 10) commitchannel := make(chan CommitInfo, 1) timeout := make(chan interface{}) Raft.eventCh = Events Raft.CommitCh = commitchannel Raft.timeoutCh = timeout config.LogDir = fmt.Sprintf("log_File_%d", myid) lg, _ := log1.Open(config.LogDir) if lg == nil { fmt.Println("Error opening Log File") } Raft.lg = *lg Raft.sm.log = &Raft.lg //Raft.lg.TruncateToEnd(0) Raft.lg.RegisterSampleEntry(Log{}) er := Raft.lg.Append(Log{Logindex: 0, Term: 0, Entry: []byte("foo")}) if er != nil { fmt.Println(er) } return }
// Create a raft object with the func New(myid int, configuration interface{}) (nd Node, err error) { //var raft RaftNode raft := new(RaftNode) config := new(Config) if config, err = ToConfigure(configuration); err != nil { return nil, err } config.Id = myid config.LogDir = fmt.Sprintf("log_%d", myid) raft.config = config raft.servl, err = cluster.New(myid, "cluster_test_config.json") if err != nil { panic(err) } lg, err := logf.Open(config.LogDir) if err != nil { //t.Fatal(err) fmt.Println(err) } lg.RegisterSampleEntry(log1{}) var dat []byte switch config.Id { case 1: dat, err = ioutil.ReadFile("persdata1") check(err) case 2: dat, err = ioutil.ReadFile("persdata2") check(err) case 3: dat, err = ioutil.ReadFile("persdata3") check(err) case 4: dat, err = ioutil.ReadFile("persdata4") check(err) case 5: dat, err = ioutil.ReadFile("persdata5") check(err) } stringtok := strings.Split(strings.TrimSpace(string(dat)), " ") term, _ := strconv.Atoi(strings.TrimSpace(stringtok[0])) votedFor, _ := strconv.Atoi(strings.TrimSpace(stringtok[1])) var prs [4]int var k int k = 0 for i := 0; i < 5; i++ { if i != config.Id-1 { a := config.Cluster[i].Id prs[k] = a k++ } } //fmt.Println(raft.config.ElectionTimeout,raft.config.HeartbeatTimeout) raft.sm = &StateMachine{id: config.Id, status: "follower", peers: prs, currentTerm: term, votenegCount: 0, votedFor: votedFor, prevLogIndex: -1, lastLogIndex: 0, nextIndex: [6]int{1, 1, 1, 1, 1, 1}} raft.sm.ElectionTimeout = raft.config.ElectionTimeout raft.sm.HeartBeatTimeout = raft.config.HeartbeatTimeout go raft.processEvents() //fmt.Println(raft.sm) go raft.sm.ProcessEvent(make([]interface{}, 1)) raft.eventCh = make(chan Event, 10) raft.timeoutCh = make(chan Time, 2) raft.commitCh = make(chan CommitInfo, 1) raft.Terminate = make(chan int, 1) raft.HbeatTimer = time.NewTicker(time.Duration(config.HeartbeatTimeout) * time.Millisecond) rand.Seed(time.Now().UnixNano()) RandNo := rand.Intn(500) raft.Timer = time.AfterFunc(time.Duration(config.ElectionTimeout+RandNo)*time.Millisecond, func() { raft.timeoutCh <- TimeoutEv{} }) raft.logRaft = *lg raft.sm.log = &raft.logRaft //raft.logRaft.TruncateToEnd(0) er := raft.logRaft.Append(log1{LogIndex: 0, LogTerm: 0, Command: []byte("init")}) if er != nil { fmt.Println(er) } /* for i := 0; i < int(raft.logRaft.GetLastIndex()); i++ { raft.sm.log[i].logIndex = i _, raft.sm.log[i].command = raft.Get(i) } */ nd = raft return nd, nil }
func New(config Config) Node { var rn RaftNode var configCluster cluster.Config var peerIds []int var nextIndex map[int]int var matchIndex map[int]int var votedAs map[int]int var LogEntries []Log var err error rn.isOn = true rn.fileDir = config.LogDir rn.appendCh = make(chan Append, ChBufSize) rn.CommitCh = make(chan Commit, ChBufSize) RegisterStructs() configCluster = retConfigFile(config) peerIds = retPeerIds(config) nextIndex = initNextIndex(peerIds) matchIndex = initMatchIndex(peerIds) votedAs = initVotedAs(peerIds) rn.serv, err = cluster.New(config.Id, configCluster) if err != nil { fmt.Println("cluster config failure") } rn.logFile, err = log.Open(rn.fileDir + "/log") if err != nil { fmt.Println("Logfile failure") } rn.stateFile, err = log.Open(config.StateFileDir) if err != nil { //fmt.Println("Statefile failure") } rn.sm.log = append(rn.sm.log, Log{Term: 0, Command: nil}) LogEntries, err = rn.retLog() if err != nil { //fmt.Println("Log retrival failure") } LogEntries = append(LogEntries, Log{Term: 0, Command: nil}) // rn.stateFile.TruncateToEnd(0) // rn.stateFile.Append(StateStore{CurrTerm: 0, VotedFor: -1, LastMatchIndex: -1}) rn.sm.initStateMachine( /* currTerm */ 0, /* votedFor */ -1, /* Log */ LogEntries, /* selfId */ config.Id, /* peerIds */ peerIds, /* electionAlarm */ config.ElectionTimeout, /* heartbeatAlarm */ config.HeartbeatTimeout, /* lastMatchIndex */ -1, /* currState --Follower*/ 1, /* commitIndex */ -1, /* leaderId */ -1, /* lastLogIndex */ -1, /* lastLogTerm */ 0, /* votedAs */ votedAs, /* nextIndex */ nextIndex, /* matchIndex */ matchIndex) /*if config.Id == 101 { rn.timer = time.NewTimer(time.Duration(100) * time.Millisecond) } else { rn.timer = time.NewTimer(time.Duration(randomNoInRange(rn.sm.electionAlarm, 2 * rn.sm.electionAlarm)) * time.Millisecond) } */ rn.timer = time.NewTimer(time.Duration(randomNoInRange(rn.sm.electionAlarm, 2*rn.sm.electionAlarm)) * time.Millisecond) //fmt.Println(configCluster,peerIds,nextIndex,matchIndex,LogEntries) go rn.start() return &rn }
func New(config Config, jsonFile string) (rnode RaftNode) { rnode.sm.serverId = config.Id rnode.sm.peerIds = make([]int64, len(config.cluster)-1, len(config.cluster)-1) k := 0 for _, peer := range config.cluster { if peer.Id != config.Id { rnode.sm.peerIds[k] = peer.Id k++ } } rnode.sm.majority = int64(math.Ceil(float64(len(config.cluster)) / 2.0)) rnode.sm.commitIndex = -1 rnode.logfile = config.LogDir + "/" + "logfile" lg, _ = log.Open(rnode.logfile) //fmt.Printf("type of log:\n",reflect.TypeOf(lg)) lg.RegisterSampleEntry(logEntry{}) //assert(err == nil) //defer lg.Close() if lg.GetLastIndex() == -1 { rnode.sm.log = []logEntry{} } else { i := lg.GetLastIndex() for j := int64(0); j <= i; j++ { data, _ := lg.Get(j) rnode.sm.log = append(rnode.sm.log, data.(logEntry)) } } rnode.sm.nextIndex = make([]int64, len(config.cluster)-1, len(config.cluster)-1) for n := 0; n < len(config.cluster)-1; n++ { rnode.sm.nextIndex[n] = int64(len(rnode.sm.log)) } rnode.sm.matchIndex = make([]int64, len(config.cluster)-1, len(config.cluster)-1) for m := 0; m < len(config.cluster)-1; m++ { rnode.sm.matchIndex[m] = -1 } //rnode.statefile = config.LogDir + "/" + "statefile" //currstate, err := log.Open(rnode.statefile) //if _,err5:=os.Stat(config.LogDir + "/" + "statefile");os.IsNotExist(err5) { /* rnode.statefile,_ = os.Create(config.LogDir + "/" + "statefile") w:=bufio.NewWriter(rnode.statefile) _,err:=fmt.Fprintf(w,"%s %s %s\n", "follower","0","0") if err!=nil { fmt.Printf("statefile write error:%v\n",err) } fmt.Printf("statefile created\n") w.Flush() rnode.sm.currentTerm = int64(0) rnode.sm.currentState = "follower"*/ //} else { var err9 error rnode.statefile, err9 = os.OpenFile(config.LogDir+"_"+"statefile", os.O_RDWR, 0666) if err9 != nil { fmt.Println(err9) } r := bufio.NewReader(rnode.statefile) var currentState, currentTerm, votedFor string _, err := fmt.Fscanf(r, "%s %s %s\n", ¤tState, ¤tTerm, &votedFor) if err != nil { fmt.Printf("statefile read error:%v\n", err) } s1, _ := strconv.Atoi(currentTerm) s2, _ := strconv.Atoi(votedFor) rnode.sm.currentTerm = int64(s1) rnode.sm.currentState = currentState rnode.sm.votedFor = int64(s2) //} //currstate.RegisterSampleEntry(NodePers{}) //assert(err == nil) //defer currstate.Close() /*if currstate.GetLastIndex() == -1 { rnode.sm.currentTerm = int64(0) rnode.sm.currentState = "follower" } else { i := currstate.GetLastIndex() h, _ := currstate.Get(i) rnode.sm.currentTerm = h.(NodePers).CurrentTerm rnode.sm.currentState = h.(NodePers).CurrentState rnode.sm.votedFor = h.(NodePers).VotedFor }*/ rnode.sm.totalvotes = int64(0) rnode.sm.novotes = int64(0) rnode.eventch = make(chan interface{}, 5000) rnode.commitch = make(chan CommitInfo, 1000) rnode.endch = make(chan bool) //rnode.timeoutch = make(chan TimeoutEv) //rnode.resettimer = 0 rnode.sm.ElectionTimeout = config.ElectionTimeout rnode.sm.HeartbeatTimeout = config.HeartbeatTimeout gob.Register(AppendEv{}) gob.Register(AppendEntriesReqEv{}) gob.Register(AppendEntriesRespEv{}) gob.Register(TimeoutEv{}) gob.Register(VoteReqEv{}) gob.Register(VoteRespEv{}) rnode.timer = time.NewTimer(time.Duration(config.ElectionTimeout) * time.Millisecond) var err3 error rnode.sm_messaging, err3 = cluster.New(int(config.Id), jsonFile) if err3 != nil { fmt.Printf("Error in sm_messaging.") } return }
// Returns a Node object func New(config Config) RaftNode { peerIds := make([]int, 0) for _, netconfig := range config.cluster { if netconfig.Id != config.Id { peerIds = append(peerIds, netconfig.Id) } } rn := RaftNode{} rn.sm = &StateMachine{id: config.Id, term: 0, commitIndex: 0, state: "Follower", peers: peerIds, votedFor: 0, log: make([]logEntry, 0), voteCount: 0, netCh: make(chan interface{}), timeoutCh: make(chan interface{}), actionCh: make(chan interface{}), clientCh: make(chan interface{}), matchIndex: map[int]int{}, nextIndex: map[int]int{}, leaderId: -1, HeartbeatTimeout: config.HeartbeatTimeout, ElectionTimeout: config.ElectionTimeout} //stateStore file rn.stateStoreFile = "stateStoreFile" + strconv.Itoa(config.Id) contents, err := ioutil.ReadFile(rn.stateStoreFile) if len(contents) != 0 { state_VotedFor := strings.Split(string(contents), " ") term, err1 := strconv.Atoi(state_VotedFor[0]) votedFor, err2 := strconv.Atoi(state_VotedFor[1]) if err1 != nil || err2 != nil { logger.Panic("Can't convert term/votedFor to int") } else { rn.sm.votedFor = votedFor rn.sm.term = term } } else { ioutil.WriteFile(rn.stateStoreFile, []byte("0 0"), 0777) } //setting log for _, peerId := range peerIds { rn.sm.matchIndex[peerId] = 0 rn.sm.nextIndex[peerId] = 1 } lg, err := log.Open(config.LogDir) if err != nil { //logger.Println("Log can't be opened/created", err) } rn.lg = lg rn.lg.RegisterSampleEntry(logEntry{}) lastIndex := int(rn.lg.GetLastIndex()) if lastIndex != -1 { for i := 0; i <= lastIndex; i++ { data, err := rn.lg.Get(int64(i)) //fmt.Println(data, err) if err != nil { logger.Panic("Read from log not possible") } rn.sm.log = append(rn.sm.log, data.(logEntry)) } } else { err = rn.lg.Append(logEntry{Term: 0, Data: []byte("Dummy")}) rn.sm.log = append(rn.sm.log, logEntry{Term: 0, Data: []byte("Dummy")}) if err != nil { //logger.Println("Couldn't write to log", err) } } //configuring server serverConfig := createServerConfig(config.cluster) rn.server, err = cluster.New(config.Id, serverConfig) if err != nil { logger.Panic("Couldn't start cluster server", err) } else { //logger.Println("ID:"+strconv.Itoa(config.Id)+" Raft Server Started succesfully") } gob.Register(AppendEntriesReqEv{}) gob.Register(AppendEntriesRespEv{}) gob.Register(VoteReqEv{}) gob.Register(VoteRespEv{}) //setting channels rn.timeoutChan = make(chan interface{}) rn.commitChan = make(chan CommitInfo) rn.eventChan = make(chan interface{}) rn.lock = &sync.Mutex{} //configuring timer timerFunc := func(rn *RaftNode) func() { return func() { rn.timeoutChan <- TimeoutEv{} } }(&rn) rn.timer = time.AfterFunc(rn.sm.ElectionTimeout, timerFunc) //logger.Println("Created new raft node") return rn }
func New(config RaftConfig, startServer bool) Node { // inits the cluster peersArray := make([]cluster.PeerConfig, len(config.cluster)) for i := 0; i < len(config.cluster); i++ { peersArray[i] = cluster.PeerConfig{Id: config.cluster[i].Id, Address: config.cluster[i].Host + ":" + strconv.Itoa(config.cluster[i].Port)} } server, err := cluster.New(config.Id, cluster.Config{Peers: peersArray, InboxSize: config.InboxSize, OutboxSize: config.OutboxSize}) // server, err := cluster.New(config.Id, "src/ss/Cluster_config.json") if err != nil { panic(err) } // inits the log lg, err := diskLog.Open(config.LogDir) if err != nil { panic(err) } defer lg.Close() lg.RegisterSampleEntry(LogStore{}) //read entries from the log numPrevLogs := lg.GetLastIndex() // should return a int64 value var logArray []LogEntry var i int64 if numPrevLogs != -1 { for i = 0; i <= numPrevLogs; i++ { data, err := lg.Get(i) // should return the Foo instance appended above if err != nil { panic(err) } logg, ok := data.(LogStore) if !ok { log.Fatal("Failed") } logArray = append(logArray, LogEntry{Index: logg.Index, Term: logg.Term, Command: logg.Data}) // creates the node's log } } // reads the node-specific file that stores lastVotedFor and term stateLog, err := diskLog.Open(strconv.Itoa(config.Id) + "_state") if err != nil { panic(err) } defer stateLog.Close() stateLog.RegisterSampleEntry(StateStore{}) //registers the data structure to store //read entries from the log stateIndex := stateLog.GetLastIndex() // should return a int64 value var lastVotedFor int = -1 var term uint = 0 // if previous state has been stored for this node, it will be at last index if stateIndex != -1 { data, err := stateLog.Get(i) // should return the Foo instance appended above if err != nil { panic(err) } state, ok := data.(StateStore) if !ok { log.Fatal("Failed") } lastVotedFor = state.VotedFor term = state.Term } ////////////////////////////////////////////////// // term = 0 // lastVotedFor = -1 ////////////////////////////////////////////////// sm := RaftServer{ State: FOLLOWER, ID: config.Id, ElectionTimeout: config.ElectionTimeout, HeartbeatTimeout: config.HeartbeatTimeout, Server: server, N: uint(len(config.cluster)), Term: term, VotedFor: lastVotedFor, LogDir: config.LogDir, StateStoreDir: strconv.Itoa(config.Id) + "_state", Log: logArray, //[]LogEntry{} TimerSet: false, VotesArray: createIntArray(len(config.cluster), -1), LeaderID: -1, CommitIndex: -1, //If the node doesn’t store the committed index to a file, it has to be //-inferred at startup. That will have to wait until the first few AppendEntry heartbeats have been responded to. ReceiveChannel: make(chan Event, NumChannels), SendChannel: make(chan Action, NumChannels), ClientCommitChannel: make(chan CommitInfo, NumChannels), QuitChannel: make(chan bool, 1)} if startServer { go sm.NodeStart() } return &sm }
func New(conf Config) Node { var rn RaftNode // initlisation of other raft node variables rn.IsWorking = true rn.TimeoutTimer = time.NewTimer(0) <-rn.TimeoutTimer.C rn.AppendEventCh = make(chan Event, 100) //rn.TimeoutEventCh = make(chan Event, 100) rn.CommitCh = make(chan CommitInfo, 100) RegisterStructs() ClustConfig := GetClusterConfig(conf) // ????? rn.NetServer, _ = cluster.New(conf.Id, ClustConfig) // ????? rn.LogFile, _ = log.Open(conf.LogFileDir) rn.StateFile, _ = log.Open(conf.StateFileDir) // initilisation of state machine rn.SM.Id = conf.Id rn.SM.Conf = conf rn.SM.State = "Follower" rn.SM.NumOfVotes = 0 rn.SM.NumOfNegVotes = 0 rn.SM.LeaderId = -1 // if rn.StateFile.GetLastIndex() != -1 { // entry, err := rn.StateFile.Get(0) // state_entry := entry.(StateEntry) // rn.SM.CurrentTerm = state_entry.Term // rn.SM.VotedFor = state_entry.VotedFor // rn.SM.CurrTermLastLogIndex = state_entry.CurrTermLastLogIndex // } else { rn.StateFile.TruncateToEnd(0) rn.SM.CurrentTerm = 0 rn.SM.VotedFor = -1 rn.SM.CurrTermLastLogIndex = -1 rn.StateFile.Append(StateEntry{Term: 0, VotedFor: -1, CurrTermLastLogIndex: -1}) //} // if rn.StateFile.GetLastIndex() != -1 { // last_index := rn.StateFile.GetLastIndex() // for i := 0; i <= last_index; i++ { // entry, err := rn.LogFile.Get(i) // log_entry := entry.(LogEntry) // rn.SM.Log = append(rn.SM.Log, log_entry) // } // } else { rn.LogFile.TruncateToEnd(0) rn.SM.Log = append(rn.SM.Log, LogEntry{Term: 0, Data: nil}) rn.LogFile.Append(LogEntry{Term: 0, Data: nil}) //} rn.SM.CommitIndex = 0 rn.SM.LastApplied = 0 for _, _ = range conf.Cluster { rn.SM.NextIndex = append(rn.SM.NextIndex, len(rn.SM.Log)) rn.SM.MatchIndex = append(rn.SM.MatchIndex, 0) } //go rn.ProcessTimers() go rn.ProcessNodeEvents() rn.TimeoutTimer.Reset(time.Millisecond * time.Duration(conf.ElectionTimeout)) return &rn }
func mkCluster(id string) (cluster.Server, error) { int_id, _ := strconv.Atoi(id) cl, err := cluster.New(int_id, "peer.json") return cl, err }