public static VoteOfCandidate 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
            {
                if (extDecoder.CheckNull())
                {
                    return(null);
                }
                else
                {
                    decoder = extDecoder;
                }
            }

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

            m.TermId   = decoder.GetULong();
            m.VoteType = (eVoteType)decoder.GetInt();

            return(m);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Node receives answer votes (to become Leader) from other nodes.
        /// Is called from tryCatch and in lock
        /// </summary>
        /// <param name="data"></param>
        void ParseVoteOfCandidate(NodeAddress address, byte[] data)
        {
            //Node received a node
            var vote = VoteOfCandidate.BiserDecode(data);

            var termState = CompareCurrentTermWithIncoming(vote.TermId);

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

            switch (vote.VoteType)
            {
            case VoteOfCandidate.eVoteType.VoteFor:
                //Calculating if node has Majority of

                //VotesQuantity++;
                VotesQuantity.Add(address.EndPointSID);

                if ((VotesQuantity.Count + 1) >= this.GetMajorityQuantity())
                {
                    //Majority

                    //Node becomes a Leader
                    this.NodeState = eNodeState.Leader;
                    this.NodeStateLog.FlushSleCache();
                    this.NodeStateLog.ClearLogAcceptance();
                    this.NodeStateLog.ClearLogEntryForDistribution();

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

                    //Stopping timers
                    this.RemoveElectionTimer();
                    this.RemoveLeaderHeartbeatWaitingTimer();

                    /*
                     * It's possible that we receive higher term from another leader
                     * (in case if this leader was disconnected for some seconds from the network,
                     * other leader can be elected and it will definitely have higher Term, so every Leader node must be ready to it)
                     */

                    this.RunLeaderTimer();
                }
                //else
                //{
                //    //Accumulating voices
                //    //Do nothing
                //}

                break;

            case VoteOfCandidate.eVoteType.VoteReject:
                //Do nothing
                break;
            }
        }
Exemplo n.º 3
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);
        }