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); }
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); } }