This is a creation in Article, where the information may have evolved or changed.
Manager
A struct (defined in manager/manager.go
) consists of a *raft.Node
member:
// 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 ......}
and raft.Node
(defined in manager/state/raft/raft.go
) contains a *events.Broadcaster
member that receives a change manager role
of message ( leader
or a follower
):
// Node represents the Raft Node useful// configuration.type Node struct { ...... leadershipBroadcast *events.Broadcaster ......}
Send change manager role
The current code is located at 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 RAF T 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 is the leader, we must cancel//any proposals that is Currently waiting for//a quorum to acknowledge them. It is the still//possible for these to become committed, but/or if that happens we'll 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)}} El Se if!wasleader && Rd. Softstate.raftstate = = Raft. Stateleader {Wasleader = true}} if Wasleader && atomic. LoadUint32 (&n.signalledleadership)! = 1 {//If all the entries in the log has become/ /committed, broadcast our leadership status. If N.caughtup () {Atomic. StoreUint32 (&n.signalledleadership, 1) n.leadershipbroadcast.write (Isleader)} } ......}
The code that receives the message is in the Manager.Run()
function ( 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()
And Manager.handleLeadershipEvents()
the code is relatively simple, no longer repeat.