Example #1
0
        private void ConvertStateFromCandidateTo(RaftState newState)
        {
            switch (newState)
            {
            case RaftState.Follower:
                logger.Info($"RaftState {Name}: Candidate->Follower");
                State = RaftState.Follower;
                VoteSuccess.Clear();     // 选举结束清除。

                LogSequence.SetVoteFor(string.Empty);
                StartRequestVoteDelayTask?.Cancel();
                StartRequestVoteDelayTask = null;
                WaitMajorityVoteTimoutTask?.Cancel();
                WaitMajorityVoteTimoutTask = null;
                StartLeaderLostTimerTask();
                return;

            case RaftState.Candidate:
                logger.Info($"RaftState {Name}: Candidate->Candidate");
                LogSequence.SetVoteFor(string.Empty);     // 先清除,在真正自荐前可以给别人投票。
                StartRequestVote();
                return;

            case RaftState.Leader:
                StartRequestVoteDelayTask?.Cancel();
                StartRequestVoteDelayTask = null;
                WaitMajorityVoteTimoutTask?.Cancel();
                WaitMajorityVoteTimoutTask = null;
                VoteSuccess.Clear();     // 选举结束清除。

                logger.Info($"RaftState {Name}: Candidate->Leader");
                State = RaftState.Leader;
                LogSequence.SetVoteFor(string.Empty);
                LeaderId = Name;     // set to self

                // (Reinitialized after election)
                var nextIndex = LogSequence.LastIndex + 1;
                Server.Config.ForEachConnector(
                    (c) =>
                {
                    var cex        = c as Server.ConnectorEx;
                    cex.NextIndex  = nextIndex;
                    cex.MatchIndex = 0;
                });

                // Upon election:
                // send initial empty AppendEntries RPCs
                // (heartbeat)to each server; repeat during
                // idle periods to prevent election timeouts(§5.2)
                LogSequence.AppendLog(new HeartbeatLog(HeartbeatLog.SetLeaderReadyEvent), false);
                HearbeatTimerTask = Scheduler.Instance.Schedule(
                    (ThisTask) =>
                {
                    var elapse = Util.Time.NowUnixMillis - LogSequence.AppendLogActiveTime;
                    if (elapse < RaftConfig.LeaderHeartbeatTimer)
                    {
                        LogSequence.AppendLog(new HeartbeatLog(), false);
                    }
                },
                    1000,
                    1000);
                return;
            }
        }
Example #2
0
 public void AppendLog(Log log, bool ApplySync = true)
 {
     LogSequence.AppendLog(log, ApplySync);
 }