Beispiel #1
0
func NewManager(_myId string, _members []string) *Manager {
	self := &Manager{
		myId:      _myId,
		members:   _members,
		votes:     make(Votes),
		threshold: util.ComputeQuorumThreshold(len(_members)),
		C:         make(chan bool, 100),
	}

	self.state = fsm.NewFSM(
		"idle",
		fsm.Events{
			{Name: "quorum", Src: []string{"idle", "elected"}, Dst: "electing"},
			{Name: "complete", Src: []string{"electing"}, Dst: "elected"},
			{Name: "next", Src: []string{"elected"}, Dst: "idle"},
		},
		fsm.Callbacks{
			"electing":      func(e *fsm.Event) { self.onElecting() },
			"enter_elected": func(e *fsm.Event) { self.onElected(e.Args[0].(string), e.Args[1].(int64)) },
			"leave_elected": func(e *fsm.Event) { self.view++ },
		},
	)

	fmt.Printf("EM: Initializing with %d members and a quorum threshold %d\n", len(self.members), self.threshold)

	return self
}
Beispiel #2
0
func NewController(_id string, _peers IdentityMap, _connMgr *ConnectionManager) *Controller {

	var members []string

	for _, peer := range _peers {
		members = append(members, peer.Id)
	}

	self := &Controller{
		peers:           _peers,
		connMgr:         _connMgr,
		myId:            _id,
		activePeers:     make(map[string]*Peer),
		quorumThreshold: util.ComputeQuorumThreshold(len(_peers)) - 1, // We don't include ourselves
		timer:           time.NewTimer(0),
		pulse:           time.NewTicker(1),
		electionManager: election.NewManager(_id, members),
		minTmo:          500,
		maxTmo:          1000,
	}

	<-self.timer.C // drain the initial event
	self.pulse.Stop()
	<-self.pulse.C // drain the initial event

	self.state = fsm.NewFSM(
		"convening",
		fsm.Events{
			{Name: "quorum", Src: []string{"convening"}, Dst: "initializing"},
			{Name: "quorum-lost", Src: []string{"initializing", "electing", "electing-restart", "following", "leading"}, Dst: "convening"},
			{Name: "elected-self", Src: []string{"initializing", "electing"}, Dst: "leading"},
			{Name: "elected-other", Src: []string{"initializing", "electing"}, Dst: "following"},
			{Name: "timeout", Src: []string{"initializing", "following", "electing"}, Dst: "electing"},
			{Name: "election", Src: []string{"following", "leading"}, Dst: "electing"},
			{Name: "heartbeat", Src: []string{"following"}, Dst: "following"},
		},
		fsm.Callbacks{
			"convening":          func(e *fsm.Event) { self.onConvening() },
			"enter_initializing": func(e *fsm.Event) { self.onInitializing() },
			"leave_initializing": func(e *fsm.Event) { self.timer.Stop() },
			"enter_following":    func(e *fsm.Event) { self.onEnterFollowing() },
			"leave_following":    func(e *fsm.Event) { self.onLeaveFollowing() },
			"enter_electing":     func(e *fsm.Event) { self.onElecting() },
			"leave_electing":     func(e *fsm.Event) { self.timer.Stop() },
			"enter_leading":      func(e *fsm.Event) { self.onEnterLeading() },
			"leave_leading":      func(e *fsm.Event) { self.onLeaveLeading() },
			"heartbeat":          func(e *fsm.Event) { self.onHeartBeat(e.Args[0].(string), e.Args[1].(int64)) },
			"before_timeout":     func(e *fsm.Event) { self.onTimeout() },
		},
	)

	return self
}