Exemplo n.º 1
0
        private int ProcessRequestVoteResult(RequestVote rpc, Connector c)
        {
            lock (this)
            {
                if (LogSequence.TrySetTerm(rpc.Result.Term))
                {
                    // new term found
                    ConvertStateTo(RaftState.Follower);
                    return(Procedure.Success);
                }
            }

            if (rpc.Result.VoteGranted && VoteSuccess.TryAdd(c.Name, c))
            {
                lock (this)
                {
                    if (
                        // 确保当前状态是选举中。没有判断这个,
                        // 后面 ConvertStateTo 也会忽略不正确的状态转换。
                        State == RaftState.Candidate
                        // 加上自己就是多数派了。
                        && VoteSuccess.Count >= RaftConfig.HalfCount)
                    {
                        ConvertStateTo(RaftState.Leader);
                    }
                }
            }
            return(Procedure.Success);
        }
Exemplo n.º 2
0
        private void SendRequestVote(SchedulerTask ThisTask)
        {
            lock (this)
            {
                VoteSuccess.Clear(); // 每次选举开始清除。

                LeaderId = string.Empty;
                LogSequence.SetVoteFor(Name); // Vote Self First.
                LogSequence.TrySetTerm(LogSequence.Term + 1);
                WaitMajorityVoteTimoutTask?.Cancel();
                WaitMajorityVoteTimoutTask = null;

                var arg = new RequestVoteArgument();
                arg.Term        = LogSequence.Term;
                arg.CandidateId = Name;
                var log = LogSequence.LastRaftLog();
                arg.LastLogIndex = log.Index;
                arg.LastLogTerm  = log.Term;

                Server.Config.ForEachConnector(
                    (c) =>
                {
                    if (false == c.IsHandshakeDone)
                    {
                        return;
                    }
                    var rpc = new RequestVote()
                    {
                        Argument = arg
                    };
                    rpc.Send(c.Socket, (p) => ProcessRequestVoteResult(rpc, c));
                    logger.Debug("{0}: SendRequestVote {1}", Name, rpc);
                });

                // 定时,如果超时选举还未完成,再次发起选举。
                WaitMajorityVoteTimoutTask = Scheduler.Instance.Schedule(
                    (ThisTask) =>
                {
                    lock (this)
                    {
                        StartRequestVoteDelayTask = null;
                        ConvertStateTo(RaftState.Candidate);
                    }
                },
                    RaftConfig.AppendEntriesTimeout + 1000);
            }
        }