這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Manager結構體(定義在manager/manager.go)包含一個*raft.Node成員:
// Manager is the cluster manager for Swarm.// This is the high-level object holding and initializing all the manager// subsystems.type Manager struct { ...... RaftNode *raft.Node ......}
而raft.Node(定義在manager/state/raft/raft.go)則包含一個*events.Broadcaster成員,用來接收改變manager role的訊息(變成leader還是follower):
// Node represents the Raft Node useful// configuration.type Node struct { ...... leadershipBroadcast *events.Broadcaster ......}
發送改變當前manager role的代碼位於manager/state/raft/raft.go:
// Run is the main loop for a Raft node, it goes along the state machine,// acting on the messages received from other Raft nodes in the cluster.//// Before running the main loop, it first starts the raft node based on saved// cluster state. If no saved state exists, it starts a single-node cluster.func (n *Node) Run(ctx context.Context) error { ...... // If we cease to be the leader, we must cancel // any proposals that are currently waiting for // a quorum to acknowledge them. It is still // possible for these to become committed, but // if that happens we will apply them as any // follower would. if rd.SoftState != nil { if wasLeader && rd.SoftState.RaftState != raft.StateLeader { wasLeader = false n.wait.cancelAll() if atomic.LoadUint32(&n.signalledLeadership) == 1 { atomic.StoreUint32(&n.signalledLeadership, 0) n.leadershipBroadcast.Write(IsFollower) } } else if !wasLeader && rd.SoftState.RaftState == raft.StateLeader { wasLeader = true } } if wasLeader && atomic.LoadUint32(&n.signalledLeadership) != 1 { // If all the entries in the log have become // committed, broadcast our leadership status. if n.caughtUp() { atomic.StoreUint32(&n.signalledLeadership, 1) n.leadershipBroadcast.Write(IsLeader) } } ......}
接收訊息的代碼在Manager.Run()函數(manager/manager.go):
// Run starts all manager sub-systems and the gRPC server at the configured// address.// The call never returns unless an error occurs or `Stop()` is called.func (m *Manager) Run(parent context.Context) error { ...... leadershipCh, cancel := m.RaftNode.SubscribeLeadership() defer cancel() go m.handleLeadershipEvents(ctx, leadershipCh) ...... go func() { err := m.RaftNode.Run(ctx) if err != nil { log.G(ctx).Error(err) m.Stop(ctx) } }() ......}
Node.SubscribeLeadership()和Manager.handleLeadershipEvents()代碼比較簡單,不再贅述。