Esempio n. 1
0
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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
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)
}
Esempio n. 4
0
// 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
}
Esempio n. 5
0
//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
}
Esempio n. 6
0
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
}
Esempio n. 7
0
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
}
Esempio n. 8
0
// 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
}
Esempio n. 9
0
// 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
}
Esempio n. 10
0
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
}
Esempio n. 11
0
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
}
Esempio n. 12
0
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)

}
Esempio n. 14
0
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
}
Esempio n. 15
0
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

}
Esempio n. 16
0
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
}
Esempio n. 17
0
// 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

}
Esempio n. 18
0
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
}
Esempio n. 19
0
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", &currentState, &currentTerm, &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
}
Esempio n. 20
0
// 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
}
Esempio n. 21
0
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
}
Esempio n. 22
0
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
}
Esempio n. 23
0
func mkCluster(id string) (cluster.Server, error) {
	int_id, _ := strconv.Atoi(id)
	cl, err := cluster.New(int_id, "peer.json")
	return cl, err
}