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); }
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(); } } }
public void UpdateData( ElectionResult electionResults, ElectionPredictionSet electionPredictions) { ElectionResults = electionResults; ElectionPredictions = electionPredictions; Model = _plotGenerator.SetupPlot(electionResults, electionPredictions); }
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); }
public void AddElectionResult(ElectionResult electionResult) { if (!(DB.ElectionResults.Any(c => c.VoterCode == electionResult.VoterCode))) { DB.ElectionResults.Add(electionResult); DB.SaveChanges(); } }
public void AddElectionResult(long voterCode, long electionOptionId) { ElectionResult newElectionResult = new ElectionResult() { VoterCode = voterCode, ElectionOptionId = electionOptionId }; ElectionResultDal.AddElectionResult(newElectionResult); }
public void Update( ElectionResult electionResults, ElectionPredictionSet electionPredictions) { _plotPairViewModel.UpdateData(electionResults, electionPredictions); Model.InvalidatePlot(true); OnPropertyChanged(() => ViewController); OnPropertyChanged(() => Model); }
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); }); }
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); }
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."); } }
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; } } }
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); }
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); }
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(); } }
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 { } }
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; } }
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 { } }
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); }
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); }
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!"; } }
public void SubmitElectionResult(string cluster, string shard, ElectionResult result) { _session.SubmitElectionResult(cluster, shard, result); }
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; } }
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); }
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 } } }