Exemplo n.º 1
0
        public static CandidateRequest BiserDecode(byte[] enc = null, Biser.Decoder extDecoder = null) //!!!!!!!!!!!!!! change return type
        {
            Biser.Decoder decoder = null;
            if (extDecoder == null)
            {
                if (enc == null || enc.Length == 0)
                {
                    return(null);
                }
                decoder = new Biser.Decoder(enc);
                if (decoder.CheckNull())
                {
                    return(null);
                }
            }
            else
            {
                decoder = new Biser.Decoder(extDecoder);
                if (decoder.IsNull)
                {
                    return(null);
                }
            }

            CandidateRequest m = new CandidateRequest();  //!!!!!!!!!!!!!! change return type

            m.TermId     = decoder.GetULong();
            m.LastLogId  = decoder.GetULong();
            m.LastTermId = decoder.GetULong();

            return(m);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Is called from tryCatch and in lock
        /// </summary>
        /// <param name="data"></param>
        void ParseCandidateRequest(NodeAddress address, byte[] data)
        {
            var             req  = CandidateRequest.BiserDecode(data);
            VoteOfCandidate vote = new VoteOfCandidate();

            vote.VoteType = VoteOfCandidate.eVoteType.VoteFor;

            var termState = CompareCurrentTermWithIncoming(req.TermId);

            vote.TermId = NodeTerm;

            switch (termState)
            {
            case eTermComparationResult.CurrentTermIsHigher:

                vote.VoteType = VoteOfCandidate.eVoteType.VoteReject;

                break;

            case eTermComparationResult.CurrentTermIsSmaller:
                //Now this Node is Follower
                break;
            }

            if (vote.VoteType == VoteOfCandidate.eVoteType.VoteFor)
            {
                switch (this.NodeState)
                {
                case eNodeState.Leader:
                    vote.VoteType = VoteOfCandidate.eVoteType.VoteReject;
                    break;

                case eNodeState.Candidate:
                    vote.VoteType = VoteOfCandidate.eVoteType.VoteReject;
                    break;

                case eNodeState.Follower:

                    //Probably we can vote for this Node (if we didn't vote for any other one)
                    if (LastVotedTermId < req.TermId)
                    {
                        //formula of voting
                        if (
                            (NodeStateLog.StateLogTerm > req.LastTermId)
                            ||
                            (
                                NodeStateLog.StateLogTerm == req.LastTermId
                                &&
                                NodeStateLog.StateLogId > req.LastLogId
                            )
                            )
                        {
                            vote.VoteType = VoteOfCandidate.eVoteType.VoteReject;
                        }
                        else
                        {
                            LastVotedTermId = req.TermId;
                            vote.VoteType   = VoteOfCandidate.eVoteType.VoteFor;

                            //Restaring Election Timer
                            this.RemoveElectionTimer();
                            this.RunElectionTimer();
                        }
                    }
                    else
                    {
                        vote.VoteType = VoteOfCandidate.eVoteType.VoteReject;
                    }

                    break;
                }
            }

            //Sending vote signal back
            //VerbosePrint("Node {0} voted to node {1} as {2}  _ParseCandidateRequest", NodeAddress.NodeAddressId, address.NodeAddressId, vote.VoteType);
            VerbosePrint($"Node {NodeAddress.NodeAddressId} ({this.NodeState}) {vote.VoteType} {address.NodeAddressId}  in  _ParseCandidateRequest");

            Sender.SendTo(address, eRaftSignalType.VoteOfCandidate, vote.SerializeBiser(), this.NodeAddress, entitySettings.EntityName);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Time to become a candidate
        /// </summary>
        /// <param name="userToken"></param>
        void ElectionTimeout(object userToken)
        {
            CandidateRequest req = null;

            try
            {
                lock (lock_Operations)
                {
                    if (Election_TimerId == 0)  //Timer was switched off and we don't need to run it again
                    {
                        return;
                    }

                    Election_TimerId = 0;

                    if (this.NodeState == eNodeState.Leader)
                    {
                        return;
                    }



                    VerbosePrint("Node {0} election timeout", NodeAddress.NodeAddressId);

                    this.NodeState = eNodeState.Candidate;

                    this.LeaderNodeAddress = null;

                    VerbosePrint("Node {0} state is {1} _ElectionTimeout", NodeAddress.NodeAddressId, this.NodeState);

                    //Voting for self
                    //VotesQuantity = 1;
                    VotesQuantity.Clear();

                    //Increasing local term number
                    NodeTerm++;

                    req = new CandidateRequest()
                    {
                        TermId     = this.NodeTerm,
                        LastLogId  = NodeStateLog.StateLogId,
                        LastTermId = NodeStateLog.StateLogTerm
                    };


                    //send to all was here

                    //Setting up new Election Timer
                    RunElectionTimer();
                }

                this.Sender.SendToAll(eRaftSignalType.CandidateRequest, req.SerializeBiser(), this.NodeAddress, entitySettings.EntityName);
            }
            catch (Exception ex)
            {
                Log.Log(new WarningLogEntry()
                {
                    Exception = ex, Method = "Raft.RaftNode.ElectionTimeout"
                });
            }
        }