Esempio n. 1
0
 public PlotModel SetupPlot(
     ElectionResult electionResults, ElectionPredictionSet electionPredictions)
 {
     ElectionResults     = electionResults;
     ElectionPredictions = electionPredictions;
     return(SetupPlot());
 }
        public void Test1()
        {
            IVotingCalculator calculator = new FPVotingCalculator(_repository);
            ElectionResult    result     = calculator.CalculateElectionResult(1);

            Assert.NotNull(result);
        }
Esempio n. 3
0
        private void Update_Click(object sender, EventArgs e)
        {
            int votes;

            if (Update.Text == "Pas aan")
            {
                if (int.TryParse(tbVotes.Text, out votes) && cbParty.SelectedItem != null)
                {
                    election.ChangeResults(cbParty.SelectedItem.ToString(), votes, sql);
                    MessageBox.Show("De uitslag is succelvol aangepast.");
                    this.Close();
                }
            }
            else if (Update.Text == "Nieuw resultaat")
            {
                DateTime temp;
                if (DateTime.TryParse(tbDateTime.Text, out temp) && int.TryParse(tbVotes.Text, out votes) && cbParty.SelectedItem != null)
                {
                    election.Name = cbElections.Text;
                    election.AddParty((Party)cbParty.SelectedItem);
                    ElectionResult result = new ElectionResult();
                    election.AddResult(result);
                    result.CalculateSeats(Convert.ToInt32(tbVotes.Text));
                    sql.NewResult(result, election.Name);
                    MessageBox.Show("De uitslag is succelvol opgeslagen.");
                    this.Close();
                }
            }
        }
Esempio n. 4
0
 public void UpdateData(
     ElectionResult electionResults, ElectionPredictionSet electionPredictions)
 {
     ElectionResults     = electionResults;
     ElectionPredictions = electionPredictions;
     Model = _plotGenerator.SetupPlot(electionResults, electionPredictions);
 }
Esempio n. 5
0
        private void SetupInterpolatedPredictions(
            IPollsProvider polls,
            ElectionResult previousElectionResult)
        {
            InterpolatedPredictions.Clear();
            if (!polls.PollsByDate.Any())
            {
                return;
            }

            // Make up a set of dummy polls from the interpolated values
            DateTime startDate = polls.PollsByDate.First().PublicationDate;
            DateTime lastDate  = polls.PollsByDate.Last().PublicationDate;
            int      numberOfInterpolatedValues = (lastDate - startDate).Days + 1;

            List <PartyPollingResultsSet> constituencyPredictors =
                PartyPollingSets.Where(x => x.IsConstituency).ToList();
            List <PartyPollingResultsSet> listPredictors =
                PartyPollingSets.Where(x => !x.IsConstituency).ToList();

            for (int i = 0; i < numberOfInterpolatedValues; i++)
            {
                OpinionPoll interpolationPoll =
                    GetInterpolationPoll(polls, startDate, i, constituencyPredictors, listPredictors);

                ElectionPrediction electionPrediction =
                    new ElectionPrediction(previousElectionResult, interpolationPoll);
                InterpolatedPredictions.Add(new PollingPrediction(electionPrediction, interpolationPoll));
            }
        }
        public void SubmitElectionResult(ElectionResult result)
        {
            ManagementCommand command = GetManagementCommand(ConfigurationCommandUtil.MethodName.SubmitElectionResult, 1);

            command.Parameters.AddParameter(result);

            ExecuteCommandOnConfigurationServer(command, false);
        }
Esempio n. 7
0
 public void AddElectionResult(ElectionResult electionResult)
 {
     if (!(DB.ElectionResults.Any(c => c.VoterCode == electionResult.VoterCode)))
     {
         DB.ElectionResults.Add(electionResult);
         DB.SaveChanges();
     }
 }
Esempio n. 8
0
        public void AddElectionResult(long voterCode, long electionOptionId)
        {
            ElectionResult newElectionResult = new ElectionResult()
            {
                VoterCode = voterCode, ElectionOptionId = electionOptionId
            };

            ElectionResultDal.AddElectionResult(newElectionResult);
        }
Esempio n. 9
0
        public void Update(
            ElectionResult electionResults,
            ElectionPredictionSet electionPredictions)
        {
            _plotPairViewModel.UpdateData(electionResults, electionPredictions);
            Model.InvalidatePlot(true);

            OnPropertyChanged(() => ViewController);
            OnPropertyChanged(() => Model);
        }
Esempio n. 10
0
        public ElectionPrediction(
            ElectionResult previousResult,
            OpinionPoll opinionPoll)
        {
            PreviousResult = previousResult;
            OpinionPoll    = opinionPoll;

            PartyPredictions = new List <PartyVoteSwing>();
            SetupPartyPredictions();
        }
        private void UploadResults(
            ModelContext modelContext,
            ElectionResultsDto dto,
            ElectoralDistrict district,
            Election election,
            Dictionary <string, Candidate> candidates)
        {
            var result = new ElectionResult()
            {
                ElectoralDistrict                 = district,
                Election                          = election,
                DataSourceUrl                     = "-",
                VotersCount                       = dto.VotersCount,
                ReceivedBallotsCount              = dto.ReceivedBallotsCount,
                EarlyIssuedBallotsCount           = dto.EarlyIssuedBallotsCount,
                IssuedInsideBallotsCount          = dto.IssuedInsideBallotsCount,
                IssuedOutsideBallotsCount         = dto.IssuedOutsideBallotsCount,
                CanceledBallotsCount              = dto.CanceledBallotsCount,
                OutsideBallotsCount               = dto.OutsideBallotsCount,
                InsideBallotsCount                = dto.InsideBallotsCount,
                InvalidBallotsCount               = dto.InvalidBallotsCount,
                ValidBallotsCount                 = dto.ValidBallotsCount,
                ReceivedAbsenteeCertificatesCount = dto.ReceivedAbsenteeCertificatesCount,
                IssuedAbsenteeCertificatesCount   = dto.IssuedAbsenteeCertificatesCount,
                AbsenteeCertificateVotersCount    = dto.AbsenteeCertificateVotersCount,
                CanceledAbsenteeCertificatesCount = dto.CanceledAbsenteeCertificatesCount,
                IssuedByHigherDistrictAbsenteeCertificatesCount = dto.IssuedByHigherDistrictAbsenteeCertificatesCount,
                LostAbsenteeCertificatesCount = dto.LostAbsenteeCertificatesCount,
                LostBallotsCount        = dto.LostBallotsCount,
                UnaccountedBallotsCount = dto.UnaccountedBallotsCount
            };

            modelContext.ElectionResults.Add(result);

            dto
            .Votes
            .ToList()
            .ForEach(voteDto =>
            {
                var vote = new ElectionCandidateVote
                {
                    ElectionResult = result,
                    Candidate      = candidates[voteDto.Key],
                    Count          = voteDto.Value
                };

                modelContext.ElectionCandidatesVotes.Add(vote);
            });
        }
Esempio n. 12
0
        public override ElectionResult GetElectionResult(GetElectionResultInput input)
        {
            var votingResult = State.VoteContract.GetVotingResult.Call(new GetVotingResultInput
            {
                VotingItemId   = State.MinerElectionVotingItemId.Value,
                SnapshotNumber = input.TermNumber,
            });

            var result = new ElectionResult
            {
                TermNumber = input.TermNumber,
                IsActive   = input.TermNumber == State.CurrentTermNumber.Value,
                Results    = { votingResult.Results }
            };

            return(result);
        }
Esempio n. 13
0
        private void btnMakeCoalition_Click(object sender, EventArgs e)
        {
            if (tbCoalitionName.Text != null && clbParties.CheckedItems.Count > 1)
            {
                List <ElectionResult> parties = new List <ElectionResult>();
                foreach (object result in clbParties.CheckedItems)
                {
                    ElectionResult res = (ElectionResult)result;
                    parties.Add(res);
                }

                Coalition coalition = new Coalition(tbCoalitionName.Text, parties);
                coalition.aMayority(parties, election);
                sql.NewCoalition(coalition);
                MessageBox.Show("Coalitie " + coalition.Name + " is gevormd.");
            }
        }
Esempio n. 14
0
        private void SetupPartyPredictions()
        {
            // Copy over the year and notes to the predicted result.
            PredictedResult = new ElectionResult
            {
                Parties = PreviousResult.Parties,
                Year    = PublishedDate.Year
            };

            // Get the party swings.
            SetupPartyVoteSwings();

            // Get the constituency swings.
            Dictionary <string, float> constituencySwingsByParty =
                PartyPredictions.ToDictionary(
                    party => party.Abbreviation,
                    party => party.PercentageConstituencyVoteSwing);

            // Copy over the constituency results from the previous and apply the swings.
            PredictedResult.FirstVotes =
                GetConstituencyResultProviderWithSwings(PreviousResult.FirstVotes, constituencySwingsByParty);

            // Get the list swings.
            Dictionary <string, float> listSwingsByParty =
                PartyPredictions.ToDictionary(
                    party => party.Abbreviation,
                    party => party.PercentageListVoteSwing);

            // Copy over the list results from the previous and apply the swings.
            PredictedResult.SecondVotes =
                GetConstituencyResultProviderWithSwings(PreviousResult.SecondVotes, listSwingsByParty);

            // Update the parties seats.
            for (int i = 0; i < PartyPredictions.Count; i++)
            {
                string    partyAbbreviation        = PartyPredictions[i].Abbreviation;
                PartyVote predictedResultPartyVote =
                    PredictedResult.PartyVotes.FirstOrDefault(x => x.Abbreviation == partyAbbreviation);

                if (predictedResultPartyVote != null)
                {
                    PartyPredictions[i].ConstituencySeats = predictedResultPartyVote.ConstituencySeats;
                    PartyPredictions[i].ListSeats         = predictedResultPartyVote.ListSeats;
                }
            }
        }
Esempio n. 15
0
        public override ElectionResult GetElectionResult(GetElectionResultInput input)
        {
            var votingResult = State.VoteContract.GetVotingResult.Call(new GetVotingResultInput
            {
                Topic       = ElectionContractConsts.Topic,
                EpochNumber = input.TermNumber,
                Sponsor     = Context.Self
            });

            var result = new ElectionResult
            {
                TermNumber = input.TermNumber,
                IsActive   = input.TermNumber == State.CurrentTermNumber.Value,
                Results    = { votingResult.Results }
            };

            return(result);
        }
Esempio n. 16
0
        public void UpdatePredictions(
            IPollsProvider polls,
            ElectionResult previousElectionResult)
        {
            Predictions.Clear();

            foreach (OpinionPoll poll in polls.PollsByDate)
            {
                ElectionPrediction electionPrediction =
                    new ElectionPrediction(previousElectionResult, poll);
                Predictions.Add(electionPrediction);
                PollingPredictions.Add(new PollingPrediction(electionPrediction, poll));
            }

            InitialisePartyPollingSets(polls);

            SetupInterpolatedPredictions(polls, previousElectionResult);

            OnPollsUpdated(null);
        }
Esempio n. 17
0
 public void Dispose()
 {
     // We lost the election, if we disposing the candidate without winning
     if (ElectionResult != ElectionResult.Won)
     {
         ElectionResult = ElectionResult.Lost;
     }
     _running.Lower();
     _stateChange.TrySetResult(null);
     _peersWaiting.Set();
     //TODO: shutdown notification of some kind?
     if (_engine.Log.IsInfoEnabled)
     {
         _engine.Log.Info($"Candidate {_engine.Tag}: Dispose");
     }
     if (_thread != null && _thread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)
     {
         _thread.Join();
     }
 }
Esempio n. 18
0
        public void NewResult(ElectionResult result, string election)
        {
            try
            {
                using (var db = new SqlConnection(connectionString))
                {
                    db.Open();
                    SqlCommand cmd = new SqlCommand("NieuwResultaat", db);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.Add(new SqlParameter("@id", result.Party.Id));
                    cmd.Parameters.Add(new SqlParameter("@stemmen", result.Votes));
                    cmd.Parameters.Add(new SqlParameter("@percentage", result.Percentage));
                    cmd.Parameters.Add(new SqlParameter("@zetels", result.Seats));
                    cmd.Parameters.Add(new SqlParameter("@verkiezing", election));

                    cmd.ExecuteNonQuery();
                }
            }
            catch { }
        }
Esempio n. 19
0
        public void Dispose()
        {
            // We lost the election, if we disposing the candidate without winning
            if (ElectionResult != ElectionResult.Won)
            {
                ElectionResult = ElectionResult.Lost;
            }
            _running.Lower();
            _stateChange.TrySetResult(null);
            _peersWaiting.Set();
            if (_engine.Log.IsInfoEnabled)
            {
                _engine.Log.Info($"Candidate {_engine.Tag}: Dispose");
            }

            if (_longRunningWork != null && _longRunningWork != PoolOfThreads.LongRunningWork.Current)
            {
                _longRunningWork.Join(Int32.MaxValue);
            }
        }
        public PartyVoteSwing(PartyVote partyVote, ElectionResult previousResult) : base(partyVote)
        {
            // See if this party stood in the previous election.
            PartyVote previousVote =
                previousResult.PartyVotes.FirstOrDefault(x => x.Abbreviation == partyVote.Abbreviation);

            if (previousVote != null)
            {
                // Set up the swings based on the previous
                PercentageConstituencyVoteSwing =
                    partyVote.PercentageConstituencyVote - previousVote.PercentageConstituencyVote;
                PercentageListVoteSwing =
                    partyVote.PercentageListVote - previousVote.PercentageListVote;
            }
            else
            {
                // Otherwise the swing is the current predicted vote
                PercentageConstituencyVoteSwing = partyVote.PercentageConstituencyVote;
                PercentageListVoteSwing         = partyVote.PercentageListVote;
            }
        }
Esempio n. 21
0
        public void UpdateResult(ElectionResult result)
        {
            try
            {
                string sql = "UPDATE UitslagRegel " +
                             "SET Stemmen = @stemmen, Percentage = @percentage, Zetels = @zetels " +
                             "WHERE UitslagId = @id";
                using (var db = new SqlConnection(connectionString))
                {
                    db.Open();
                    SqlCommand cmd = new SqlCommand(sql, db);
                    cmd.Parameters.Add(new SqlParameter("@id", result.ResultId));
                    cmd.Parameters.Add(new SqlParameter("@stemmen", result.Votes));
                    cmd.Parameters.Add(new SqlParameter("@percentage", result.Percentage));
                    cmd.Parameters.Add(new SqlParameter("@zetels", result.Seats));

                    cmd.ExecuteNonQuery();
                }
            }
            catch { }
        }
Esempio n. 22
0
        public ElectionResult CalculateElectionResult(int positionId)
        {
            Position position = _repository.GetPosition(positionId);

            // Set up the Nominees for the one and only round of voting
            List <ElectionRoundNomineeResult> nomineeResults = new List <ElectionRoundNomineeResult>();

            foreach (Nominee nominee in position.Nominees)
            {
                nomineeResults.Add(new ElectionRoundNomineeResult()
                {
                    NomineeId = nominee.Id,
                    Votes     = position.Votes.Count(v => v.NomineeId == nominee.Id &&
                                                     !v.HasAbstained &&
                                                     v.PreferenceOrder == 1)
                });
            }

            // Create the one and only round result
            ElectionRoundResult roundResult = new ElectionRoundResult()
            {
                NomineeResults = nomineeResults,
                Round          = 1,
                TotalVotes     = nomineeResults.Sum(n => n.Votes),
            };

            // ... and the generic result object
            ElectionResult result = new ElectionResult()
            {
                PositionId          = positionId,
                SuccessfulNomineeId = nomineeResults.Aggregate((n1, n2) => n1.Votes > n2.Votes ? n1 : n2).NomineeId,
                RoundResults        = new List <ElectionRoundResult>()
            };

            result.RoundResults.Add(roundResult);

            return(result);
        }
Esempio n. 23
0
        public ElectionResult GetElectionResult()
        {
            int            votingCount    = 0;
            ElectionResult electionResult = new ElectionResult();


            if (IsVotingCompleted)
            {
                foreach (KeyValuePair <ServerNode, ElectionVote> serverVote in _electionVotes)
                {
                    if (serverVote.Value.NodeVote.Equals(ElectionVote.Vote.yes))
                    {
                        votingCount++;
                        electionResult.Voters.Add(serverVote.Key);
                    }
                }
                electionResult.ElectionId = ElectionId;

                if (votingCount.Equals(_voters.Count()))
                {
                    electionResult.ElectedPrimary = ElectionId.RequestingNode;
                    electionResult.PollingResult  = ElectionResult.Result.PrimarySelected;
                }
                else
                {
                    electionResult.ElectedPrimary = null;
                    electionResult.PollingResult  = ElectionResult.Result.NoChangeInMembership;
                }
            }

            else
            {
                electionResult.ElectionId     = ElectionId;
                electionResult.ElectedPrimary = null;
                electionResult.PollingResult  = ElectionResult.Result.NoChangeInMembership;
            }
            return(electionResult);
        }
Esempio n. 24
0
        private void clbParties_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            Coalition coalition = new Coalition();

            foreach (object result in clbParties.CheckedItems)
            {
                ElectionResult res = (ElectionResult)result;
                coalition.Parties.Add(res);
            }
            if (e.NewValue == CheckState.Checked)
            {
                ElectionResult result = (ElectionResult)clbParties.Items[e.Index];
                coalition.Parties.Add(result);
            }
            if (coalition.aMayority(results, election) == true)
            {
                lblMayority.Text = "Deze coalitie heeft een meerderheid!";
            }
            else
            {
                lblMayority.Text = "Deze coalitie heeft een minderheid!";
            }
        }
Esempio n. 25
0
 public void SubmitElectionResult(string cluster, string shard, ElectionResult result)
 {
     _session.SubmitElectionResult(cluster, shard, result);
 }
Esempio n. 26
0
        private void Run()
        {
            var ambassadorsToRemove = new List <CandidateAmbassador>();

            try
            {
                try
                {
                    // Operation may fail, that's why we don't RaiseOrDie
                    _running.Raise();
                    ElectionTerm = _engine.CurrentTerm;
                    if (_engine.Log.IsInfoEnabled)
                    {
                        _engine.Log.Info($"Candidate {_engine.Tag}: Starting elections");
                    }
                    ClusterTopology clusterTopology;
                    using (_engine.ContextPool.AllocateOperationContext(out ClusterOperationContext context))
                        using (context.OpenReadTransaction())
                        {
                            clusterTopology = _engine.GetTopology(context);
                        }

                    if (clusterTopology.Members.Count == 1)
                    {
                        CastVoteForSelf(ElectionTerm + 1, "Single member cluster, natural leader");
                        _engine.SwitchToLeaderState(ElectionTerm, ClusterCommandsVersionManager.CurrentClusterMinimalVersion,
                                                    "I'm the only one in the cluster, so no need for elections, I rule.");
                        return;
                    }

                    if (_engine.RequestSnapshot)
                    {
                        // we aren't allowed to be elected for leadership if we requested a snapshot
                        if (_engine.Log.IsOperationsEnabled)
                        {
                            _engine.Log.Operations("we aren't allowed to be elected for leadership if we requested a snapshot");
                        }
                        return;
                    }

                    if (IsForcedElection)
                    {
                        CastVoteForSelf(ElectionTerm + 1, "Voting for self in forced elections");
                    }
                    else
                    {
                        ElectionTerm = ElectionTerm + 1;
                    }

                    foreach (var voter in clusterTopology.Members)
                    {
                        if (voter.Key == _engine.Tag)
                        {
                            continue; // we already voted for ourselves
                        }
                        var candidateAmbassador = new CandidateAmbassador(_engine, this, voter.Key, voter.Value);
                        _voters = new List <CandidateAmbassador>(_voters)
                        {
                            candidateAmbassador
                        };
                        _engine.AppendStateDisposable(this, candidateAmbassador); // concurrency exception here will dispose the current candidate and it ambassadors
                        candidateAmbassador.Start();
                    }
                    while (_running && _engine.CurrentState == RachisState.Candidate)
                    {
                        if (_peersWaiting.WaitOne(_engine.Timeout.TimeoutPeriod) == false)
                        {
                            ElectionTerm = _engine.CurrentTerm + 1;
                            _engine.RandomizeTimeout(extend: true);

                            StateChange(); // will wake ambassadors and make them ping peers again
                            continue;
                        }
                        if (_running == false)
                        {
                            return;
                        }

                        _peersWaiting.Reset();

                        var trialElectionsCount = 1;
                        var realElectionsCount  = 1;
                        foreach (var ambassador in _voters)
                        {
                            if (ambassador.NotInTopology)
                            {
                                MoveCandidateToPassive("A leader node has indicated that I'm not in their topology, I was probably kicked out.");
                                return;
                            }

                            if (ambassador.TopologyMismatch)
                            {
                                ambassadorsToRemove.Add(ambassador);
                                continue;
                            }

                            if (ambassador.RealElectionWonAtTerm == ElectionTerm)
                            {
                                realElectionsCount++;
                            }
                            if (ambassador.TrialElectionWonAtTerm == ElectionTerm)
                            {
                                trialElectionsCount++;
                            }
                        }

                        if (StillHavePeers(ambassadorsToRemove) == false)
                        {
                            MoveCandidateToPassive("I'm left alone in the cluster.");
                            return;
                        }

                        var majority = ((_voters.Count + 1) / 2) + 1;

                        if (realElectionsCount >= majority)
                        {
                            ElectionResult = ElectionResult.Won;
                            _running.Lower();

                            var connections = new Dictionary <string, RemoteConnection>();
                            var versions    = new List <int>
                            {
                                ClusterCommandsVersionManager.MyCommandsVersion
                            };

                            foreach (var candidateAmbassador in _voters)
                            {
                                if (candidateAmbassador.ClusterCommandsVersion > 0)
                                {
                                    versions.Add(candidateAmbassador.ClusterCommandsVersion);
                                }

                                if (candidateAmbassador.TryGetPublishedConnection(out var connection))
                                {
                                    connections[candidateAmbassador.Tag] = connection;
                                }
                            }
                            StateChange();

                            var    minimalVersion = ClusterCommandsVersionManager.GetClusterMinimalVersion(versions, _engine.MaximalVersion);
                            string msg            = $"Was elected by {realElectionsCount} nodes for leadership in term {ElectionTerm} with cluster version of {minimalVersion}";

                            _engine.SwitchToLeaderState(ElectionTerm, minimalVersion, msg, connections);
                            break;
                        }
                        if (RunRealElectionAtTerm != ElectionTerm &&
                            trialElectionsCount >= majority)
                        {
                            CastVoteForSelf(ElectionTerm, "Won in the trial elections");
                        }
                    }
                }
                catch (Exception e)
                {
                    if (_engine.Log.IsInfoEnabled)
                    {
                        _engine.Log.Info($"Candidate {_engine.Tag}: Failure during candidacy run with current state of {_engine.CurrentState}", e);
                    }
                    if (_engine.CurrentState == RachisState.Candidate)
                    {
                        // if we are still a candidate, start the candidacy again.
                        _engine.SwitchToCandidateState("An error occurred during the last candidacy: " + e);
                    }
                    else if (_engine.CurrentState != RachisState.Passive)
                    {
                        _engine.Timeout.Start(_engine.SwitchToCandidateStateOnTimeout);
                    }
                }
            }
            finally
            {
                try
                {
                    Dispose();
                }
                catch (Exception)
                {
                    // nothing to be done here
                }
            }
        }
 public void SubmitElectionResult(ElectionResult result)
 {
     _shardSession.SubmitElectionResult(result);
 }
        public void TriggerElectionMechanism(Activity activity, Server server, LocalShardHeartbeatReporting heartbeatReport, Membership existingMembership)
        {
            LoggerManager.Instance.SetThreadContext(new LoggerContext()
            {
                ShardName = _context.LocalShardName != null ? _context.LocalShardName : "", DatabaseName = ""
            });
            if (existingMembership == null)
            {
                existingMembership = new Membership();
            }
            ShardConfiguration sConfig = null;

            //Get the shard configuration
            if (_clusterConfigMgr != null)
            {
                sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName);
            }
            IList <Address>      activeNodes       = null;
            MembershipChangeArgs args              = new MembershipChangeArgs();
            ServerNodes          staticServerNodes = null;

            if (sConfig == null || sConfig.Servers == null)
            {
                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TiggerElectionMechanism() ", "The shard " + _context.LocalShardName + " does not exist in the configuration.");
                }
                return;
            }
            staticServerNodes = sConfig.Servers;
            ElectionResult result = null;

            if (heartbeatReport != null)
            {
                activeNodes = heartbeatReport.GetReportTable.Keys.ToList();
            }

            Address activityNode = null;

            if (server == null)
            {
                activityNode = _context.LocalAddress;
            }
            else
            {
                activityNode = server.Address;
            }

            switch (activity)
            {
            case Activity.NodeJoining:
                if (server == null)
                {
                    return;
                }
                //On node join, we need to get membership from the config server for the first time.
                Membership csMembership = _context.ConfigurationSession.GetMembershipInfo(_context.ClusterName, _context.LocalShardName);
                ServerNode joiningNode  = sConfig.Servers.GetServerNode(server.Address.IpAddress.ToString());
                // If the added node is configured while the cluster is up and running, do the following.
                if (joiningNode == null)
                {
                    if (_clusterConfigMgr != null)
                    {
                        _clusterConfigMgr.UpdateClusterConfiguration();
                        sConfig = _clusterConfigMgr.GetShardConfiguration(_context.LocalShardName);
                    }
                    if (sConfig == null)
                    {
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "The shard " + _context.LocalShardName + " does not exist in the configuration.");
                        }
                        return;
                    }
                    joiningNode = sConfig.Servers.GetServerNode(server.Address.IpAddress.ToString());
                }
                if (joiningNode == null)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "The node " + server.Address + " is not part of the configuration.");
                    }
                    return;
                }

                if (existingMembership == null || existingMembership.Servers == null || !existingMembership.Servers.Contains(joiningNode))
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Debug("ElectBasedMemSt.TriggerElectMech", "Node joining activity triggered for " + activityNode);
                    }
                }
                bool        thisNodeIsPrimary = false;
                OperationId lastOpId          = null;

                if (heartbeatReport != null && heartbeatReport.GetReportTable.ContainsKey(server.Address))
                {
                    args.ServerName = _context.LocalAddress;
                    args.ElectionId = null;
                    args.ChangeType = MembershipChangeArgs.MembershipChangeType.NodeJoined;

                    if (server.Address.Equals(_context.LocalAddress))
                    {
                        _context.ConfigurationSession.ReportNodeJoining(_context.ClusterName, _context.LocalShardName, sConfig.Servers.GetServerNode(_context.LocalAddress.IpAddress.ToString()));

                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", server.Address + " reported its joining to the config server. ");
                        }

                        //if the primary is not null and the channel is not disconnected, it can be set here.
                        if ((existingMembership == null || existingMembership.Primary == null) && csMembership.Primary != null && _shard.ActiveChannelsList.Contains(new Server(new Address(csMembership.Primary.Name, sConfig.Port), Status.Initializing)) && ObeysMajorityRule(_shard.ActiveChannelsList.Count, sConfig.Servers.Nodes.Count))
                        {
                            args.ServerName = new Address(csMembership.Primary.Name, sConfig.Port);
                            args.ElectionId = csMembership.ElectionId;
                            args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimarySet;
                            //if the node which was lost comes back up before the CS or the nodes can declare it dead,
                            //it should resume its status as a primary. There should be no need for an election in this case.
                            if (args.ServerName.Equals(_context.LocalAddress))
                            {
                                thisNodeIsPrimary = true;
                            }
                        }
                    }

                    if (thisNodeIsPrimary)
                    {
                        if (csMembership.ElectionId != null && LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "election_id: " + csMembership.ElectionId.Id + " election time :" + csMembership.ElectionId.ElectionTime);
                        }


                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "I am already declared primary");
                        }
                        lastOpId = LastOperationId;
                        ChangeMembershipShardwide(args);
                    }
                    else
                    {
                        ((LocalShard)_shard).OnMembershipChanged(args);
                    }

                    if (server.Address.Equals(_context.LocalAddress))
                    {
                        ServerNode sNode = sConfig.Servers.GetServerNode(_context.LocalAddress.IpAddress.ToString());
                        if (sNode == null)
                        {
                            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsWarnEnabled)
                            {
                                LoggerManager.Instance.ShardLogger.Warn("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "The node " + sNode.Name + " does not exist in the configuration.");
                            }
                            return;
                        }

                        _context.ConfigurationSession.ReportHeartbeat(_context.ClusterName, _context.LocalShardName, sNode, existingMembership, lastOpId);
                    }
                }
                else
                {
                    if (existingMembership.Primary != null && existingMembership.Primary.Name.Equals(server.Address.IpAddress.ToString()))
                    {
                        if (sConfig.Servers == null || sConfig.Servers.Nodes == null || !ObeysMajorityRule(activeNodes.Count, sConfig.Servers.Nodes.Count))
                        {
                            _context.ConfigurationSession.SetNodeStatus(_context.ClusterName, _context.LocalShardName, existingMembership.Primary, NodeRole.None);
                            args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted;
                            args.ServerName = _context.LocalAddress;
                            ChangeMembershipShardwide(args);
                            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                            {
                                LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", " Node addition activity occured. Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted.");
                            }
                            return;
                        }
                    }
                }

                break;

            case Activity.NodeLeaving:
                if (server == null)
                {
                    return;
                }
                bool hasMajority = ObeysMajorityRule(activeNodes.Count, staticServerNodes.Nodes.Count);
                args.ServerName = server.Address;
                args.ChangeType = MembershipChangeArgs.MembershipChangeType.NodeLeft;

                _clusterConfigMgr.UpdateClusterConfiguration();

                if (existingMembership.Primary != null)
                {
                    // if the existing primary is actually the node lost, we need to update the configuration.

                    if (existingMembership.Primary.Name == server.Address.IpAddress.ToString())
                    {
                        //if Primary leaves, it should be updated locally.
                        args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryLost;
                        if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                        {
                            LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", "Node leaving activity triggered for " + server.Address + " . Primary lost.");
                        }
                    }
                    else if (existingMembership.Primary.Name == _context.LocalAddress.IpAddress.ToString())     // if the existing primary is the local node, we need to check for possible demotion of the current primary.
                    {
                        if (!hasMajority)
                        {
                            _context.ConfigurationSession.SetNodeStatus(_context.ClusterName, _context.LocalShardName, existingMembership.Primary, NodeRole.None);
                            args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted;
                            args.ServerName = _context.LocalAddress;
                            ChangeMembershipShardwide(args);

                            if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                            {
                                LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", " Node leaving activity occurred. Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted.");
                            }

                            return;
                        }
                    }
                }

                ((LocalShard)_shard).OnMembershipChanged(args);

                break;

            case Activity.GeneralElectionsTriggered:
            case Activity.TakeoverElectionsTriggered:
                // this is where the actual election mechanism takes place.

                //Step 1: if no node in the heartbeat table has a primary and there is no primary in the local node's membership, we proceed forward.
                //Else if there is a primary but this looks like the takeover election mechanism, we proceed along as well.
                if ((activity.Equals(Activity.GeneralElectionsTriggered) && !heartbeatReport.PrimaryExists() && existingMembership.Primary == null) || (activity.Equals(Activity.TakeoverElectionsTriggered) && heartbeatReport.PrimaryExists()))
                {
                    //Step 2: we verify that this node has a majority of the shard nodes connected to it.
                    if (activeNodes != null && ObeysMajorityRule(activeNodes.Count, staticServerNodes.Nodes.Count))
                    {
                        //Step 3: Perform the initial sanity check. (Speculative phase)
                        if (ShouldIInitiateElection(heartbeatReport, activity))
                        {
                            if (existingMembership != null && existingMembership.Primary != null && activity == Activity.GeneralElectionsTriggered)
                            {
                                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                                {
                                    LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "A primary has already been selected for "
                                                                            + _context.LocalShardName + " hence exiting the election mechanism.");
                                }
                                return;
                            }
                            //Step 4: The elections take place in real. (Authoritative Phase)
                            result = HoldElection(heartbeatReport, activity);
                            if (result != null)
                            {
                                if (result.PollingResult == ElectionResult.Result.PrimarySelected)
                                {
                                    //if the shard is undergoing the takeover election mechanism, the old primary needs to
                                    //be demoted first.
                                    bool oldPrimaryDemoted = false;
                                    if (activity == Activity.TakeoverElectionsTriggered)
                                    {
                                        MembershipChangeArgs args2 = new MembershipChangeArgs();
                                        args2.ChangeType = MembershipChangeArgs.MembershipChangeType.ForcefullyDemotePrimary;
                                        args2.ServerName = _context.LocalAddress;
                                        args2.ElectionId = existingMembership.ElectionId;

                                        Message msg = new Message();
                                        msg.Payload       = args2;
                                        msg.MessageType   = MessageType.MembershipOperation;
                                        msg.NeedsResponse = true;
                                        ShardRequestBase <bool> request = _shard.CreateUnicastRequest <bool>(new Server(new Address(existingMembership.Primary.Name, sConfig.Port), Status.Running), msg);
                                        IAsyncResult            result2 = request.BeginExecute();
                                        oldPrimaryDemoted = request.EndExecute(result2);
                                    }
                                    //Submit the result to the CS.
                                    if (activity == Activity.GeneralElectionsTriggered || (activity == Activity.TakeoverElectionsTriggered && oldPrimaryDemoted))
                                    {
                                        _context.ConfigurationSession.SubmitElectionResult(_context.ClusterName.ToLower(), _context.LocalShardName.ToLower(), result);
                                    }
                                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                                    {
                                        LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", "Election result submitted for shard " + _context.LocalShardName.ToString());
                                    }

                                    _context.ElectionResult = result;
                                    args.ServerName         = _context.LocalAddress;
                                    args.ElectionId         = result.ElectionId;
                                    args.ChangeType         = MembershipChangeArgs.MembershipChangeType.PrimarySelected;
                                    //Once, the result is submitted, inform the shard nodes.
                                    ChangeMembershipShardwide(args);
                                    _context.ConfigurationSession.ReportHeartbeat(_context.ClusterName, _context.LocalShardName, result.ElectedPrimary, existingMembership, LastOperationId);
                                }
                                //Finally, end this round of elections.
                                _context.ConfigurationSession.EndElection(_context.ClusterName, _context.LocalShardName, result.ElectionId);
                            }
                        }
                    }
                }

                break;

            case Activity.CSDisconnected:
                //this is called whenever a node loses connection with the config server.

                if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                {
                    LoggerManager.Instance.ShardLogger.Debug("ElectionBasedMembershipStrategy.TriggerElectionMechanism() ", "Config Server disconnected. ");
                }
                //if the number of configured nodes are even and the primary loses connection with the CS, it needs to demote itself.
                if (existingMembership != null && existingMembership.Primary != null && existingMembership.Primary.Name == _context.LocalAddress.IpAddress.ToString() && staticServerNodes.Nodes.Count % 2 == 0)
                {
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsDebugEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Debug("electBasedMemSt.TriggerElectMech", " Connection of the node " + _context.LocalAddress.ToString() + " with the config server is lost.");
                    }

                    args.ServerName = _context.LocalAddress;
                    args.ElectionId = existingMembership.ElectionId;
                    args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted;
                    ChangeMembershipShardwide(args);
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", " Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted because the primary lost connection with the CS.");
                    }
                }
                break;

            case Activity.ForcefulPrimaryDemotion:
                if (existingMembership != null && existingMembership.Primary != null && existingMembership.Primary.Name == _context.LocalAddress.IpAddress.ToString())
                {
                    _context.ConfigurationSession.SetNodeStatus(_context.ClusterName, _context.LocalShardName, existingMembership.Primary, NodeRole.None);

                    args.ChangeType = MembershipChangeArgs.MembershipChangeType.PrimaryDemoted;
                    args.ServerName = _context.LocalAddress;
                    if (LoggerManager.Instance.ShardLogger != null && LoggerManager.Instance.ShardLogger.IsInfoEnabled)
                    {
                        LoggerManager.Instance.ShardLogger.Info("electBasedMemSt.TriggerElectMech", "Primary node " + _context.LocalAddress.IpAddress.ToString() + " demoted in order to complete the take over election mechanism. ");
                    }

                    ((LocalShard)_shard).OnMembershipChanged(args);
                }
                break;
            }
        }
Esempio n. 29
0
        public ElectionResult CalculateElectionResult(int positionId)
        {
            Position position = _repository.GetPosition(positionId);
            int      round    = 1;

            // Create the generic result object
            ElectionResult result = new ElectionResult()
            {
                PositionId   = positionId,
                RoundResults = new List <ElectionRoundResult>()
            };

            // Set up the first round of voting
            ElectionRoundResult roundResult = new ElectionRoundResult()
            {
                NomineeResults = new List <ElectionRoundNomineeResult>(),
                Round          = round
            };

            foreach (Nominee nominee in position.Nominees.Where(n => !position.Election.IsNominationConfirmationRequired || n.HasConfirmedNomination))
            {
                roundResult.NomineeResults.Add(new ElectionRoundNomineeResult()
                {
                    NomineeId = nominee.Id,
                    Votes     = 0
                });
            }

            // Repeat until we have a winner with majority
            while (result.SuccessfulNomineeId != 0)
            {
                // Record the votes for this round
                foreach (int userId in position.Votes.Select(v => v.UserId).Distinct())
                {
                    List <Vote> userVotes    = position.Votes.Where(v => v.UserId == userId).OrderBy(v => v.PreferenceOrder).ToList();
                    bool        voteRecorded = false;
                    for (int i = 0; i < userVotes.Count() && !voteRecorded; i++)
                    {
                        if (!userVotes[i].HasAbstained &&
                            //position.RoleTypeId == userVotes[i].User.MembershipType.R
                            roundResult.NomineeResults.Any(nr => nr.NomineeId == userVotes[i].NomineeId))
                        {
                            roundResult.NomineeResults.Single(nr => nr.NomineeId == userVotes[i].NomineeId).Votes++;
                            voteRecorded = true;
                        }
                    }

                    if (voteRecorded)
                    {
                        roundResult.TotalVotes++;
                    }
                    else
                    {
                        roundResult.InvalidVotes++;
                    }
                }

                result.RoundResults.Add(roundResult);

                // Do we have a majority winner?
                if (roundResult.NomineeResults.Any(nr => nr.Votes > (roundResult.TotalVotes / 2)))
                {
                    result.SuccessfulNomineeId = roundResult.NomineeResults.Single(nr => nr.Votes > (roundResult.TotalVotes / 2)).NomineeId;
                }
                else
                {
                    // Set up the next round of voting
                    round++;
                    int minimumVotes = roundResult.NomineeResults.Select(nr => nr.Votes).Min();

                    roundResult = new ElectionRoundResult()
                    {
                        NomineeResults = new List <ElectionRoundNomineeResult>(),
                        Round          = round
                    };

                    foreach (ElectionRoundNomineeResult nomineeResult in result.RoundResults.Single(rr => rr.Round == (round - 1)).NomineeResults.Where(nr => nr.Votes > minimumVotes))
                    {
                        roundResult.NomineeResults.Add(new ElectionRoundNomineeResult()
                        {
                            NomineeId = nomineeResult.NomineeId,
                            Votes     = 0
                        });
                    }
                }
            }

            result.RoundResults.Add(roundResult);

            return(result);
        }
Esempio n. 30
0
        private void Run()
        {
            try
            {
                try
                {
                    // Operation may fail, that's why we don't RaiseOrDie
                    _running.Raise();
                    ElectionTerm = _engine.CurrentTerm;
                    if (_engine.Log.IsInfoEnabled)
                    {
                        _engine.Log.Info($"Candidate {_engine.Tag}: Starting elections");
                    }
                    ClusterTopology clusterTopology;
                    using (_engine.ContextPool.AllocateOperationContext(out TransactionOperationContext context))
                        using (context.OpenReadTransaction())
                        {
                            clusterTopology = _engine.GetTopology(context);
                        }

                    if (clusterTopology.Members.Count == 1)
                    {
                        CastVoteForSelf(ElectionTerm + 1, "Single member cluster, natural leader");
                        _engine.SwitchToLeaderState(ElectionTerm, "I'm the only one in the cluster, so no need for elections, I rule.");
                        return;
                    }

                    if (IsForcedElection)
                    {
                        CastVoteForSelf(ElectionTerm + 1, "Voting for self in forced elections");
                    }
                    else
                    {
                        ElectionTerm = ElectionTerm + 1;
                    }

                    foreach (var voter in clusterTopology.Members)
                    {
                        if (voter.Key == _engine.Tag)
                        {
                            continue; // we already voted for ourselves
                        }
                        var candidateAmbassador = new CandidateAmbassador(_engine, this, voter.Key, voter.Value,
                                                                          _engine.ClusterCertificate);
                        _voters.Add(candidateAmbassador);
                        try
                        {
                            _engine.AppendStateDisposable(this, candidateAmbassador);
                        }
                        catch (ConcurrencyException)
                        {
                            foreach (var ambassador in _voters)
                            {
                                ambassador.Dispose();
                            }
                            return; // we lost the election, because someone else changed our state to follower
                        }
                        candidateAmbassador.Start();
                    }
                    while (_running && _engine.CurrentState == RachisState.Candidate)
                    {
                        if (_peersWaiting.WaitOne(_engine.Timeout.TimeoutPeriod) == false)
                        {
                            ElectionTerm = _engine.CurrentTerm;

                            // timeout?
                            if (IsForcedElection)
                            {
                                CastVoteForSelf(ElectionTerm + 1, "Timeout during forced elections");
                            }
                            else
                            {
                                ElectionTerm = ElectionTerm + 1;
                            }
                            _engine.RandomizeTimeout(extend: true);

                            StateChange(); // will wake ambassadors and make them ping peers again
                            continue;
                        }
                        if (_running == false)
                        {
                            return;
                        }

                        _peersWaiting.Reset();

                        bool removedFromTopology = false;
                        var  trialElectionsCount = 1;
                        var  realElectionsCount  = 1;
                        foreach (var ambassador in _voters)
                        {
                            if (ambassador.NotInTopology)
                            {
                                removedFromTopology = true;
                                break;
                            }
                            if (ambassador.RealElectionWonAtTerm == ElectionTerm)
                            {
                                realElectionsCount++;
                            }
                            if (ambassador.TrialElectionWonAtTerm == ElectionTerm)
                            {
                                trialElectionsCount++;
                            }
                        }

                        var majority = ((_voters.Count + 1) / 2) + 1;

                        if (removedFromTopology)
                        {
                            if (_engine.Log.IsInfoEnabled)
                            {
                                _engine.Log.Info(
                                    $"Candidate {_engine.Tag}: A leader node has indicated that I'm not in their topology, I was probably kicked out. Moving to passive mode");
                            }
                            _engine.SetNewState(RachisState.Passive, this, _engine.CurrentTerm,
                                                "I just learned from the leader that I'm not in their topology, moving to passive state");
                            break;
                        }

                        if (realElectionsCount >= majority)
                        {
                            ElectionResult = ElectionResult.Won;
                            _running.Lower();
                            StateChange();

                            var connections = new Dictionary <string, RemoteConnection>();
                            foreach (var candidateAmbassador in _voters)
                            {
                                connections[candidateAmbassador.Tag] = candidateAmbassador.Connection;
                            }
                            _engine.SwitchToLeaderState(ElectionTerm, $"Was elected by {realElectionsCount} nodes to leadership in {ElectionTerm}", connections);

                            break;
                        }
                        if (RunRealElectionAtTerm != ElectionTerm &&
                            trialElectionsCount >= majority)
                        {
                            CastVoteForSelf(ElectionTerm, "Won in the trial elections");
                        }
                    }
                }
                catch (Exception e)
                {
                    if (_engine.Log.IsInfoEnabled)
                    {
                        _engine.Log.Info($"Candidate {_engine.Tag}: Failure during candidacy run with current state of {_engine.CurrentState}", e);
                    }
                    if (_engine.CurrentState == RachisState.Candidate)
                    {
                        // if we are still a candidate, start the candidacy again.
                        _engine.SwitchToCandidateState("An error occured during the last candidacy: " + e);
                    }
                    else if (_engine.CurrentState != RachisState.Passive)
                    {
                        _engine.Timeout.Start(_engine.SwitchToCandidateStateOnTimeout);
                    }
                }
            }
            finally
            {
                try
                {
                    Dispose();
                }
                catch (Exception)
                {
                    // nothing to be done here
                }
            }
        }