private void TryCommitView(List <AcceptViewProposal> underlingsList, AcceptViewProposal bestState) { if (IsSelfPromotionAllowed()) { Utils.Print($" [o] Commiting View Change..."); Task <ReplyData>[] tasksArray = InitiateServerCalls(underlingsList); // We don't care about those replicas after informing them they should commit. If they fail, someone will detect it sooner or later. } AllowSelfPromotion(); }
private AcceptViewProposal SelectBestInitialState(List <AcceptViewProposal> underlingsList) { AcceptViewProposal bestProposal = underlingsList[0]; foreach (AcceptViewProposal underlingProposal in underlingsList) { View currentUnderlingView = underlingProposal.ServerView; if (Utils.IsOtherViewBetter(bestProposal.ServerView, currentUnderlingView)) { bestProposal = underlingProposal; } } return(bestProposal); }
public View TryViewChange(List <ServerData> knownLivingServers) { // TODO >> When servers accept a commit message they should end all their requests, alt incomming requests and wait for a commit. // TODO >> After commit is done they should resume the requests int cancelled = 0; AllowSelfPromotion(); Utils.Print(" [o] Proposing new View to known living servers..."); #region Initialization CancellationTokenSource tokenSource = new CancellationTokenSource(); tokenSource.CancelAfter(timeout); CancellationToken cancellationToken = tokenSource.Token; // Generate the new View. serverView.IncrementViewId(); serverView.PromoteViewManager(managerOwner.ServerData); serverView.ReplicasList = knownLivingServers; List <AcceptViewProposal> underlingsList = new List <AcceptViewProposal>(); Task <ReplyData>[] tasksArray = InitiateServerCalls(serverView, cancellationToken); try { Task.WaitAll(tasksArray, cancellationToken); } catch (OperationCanceledException) { cancelled++; } bool aServerExplicitlyRefused = false; for (int tidx = 0; tidx < tasksArray.Length; tidx++) { Task <ReplyData> task = tasksArray[tidx]; if (Utils.IsValidRemoteReply(task, typeof(AcceptViewProposal))) { underlingsList.Add((AcceptViewProposal)task.Result); } else if (Utils.IsValidRemoteReply(task, typeof(RejectViewProposal))) { aServerExplicitlyRefused = true; } else { knownLivingServers.Remove(((NoReply)task.Result).ServerData); } } #endregion if (Utils.MajorityHasAccepted(underlingsList.Count, tasksArray.Length - cancelled)) { AcceptViewProposal bestProposal = SelectBestInitialState(underlingsList); TryCommitView(underlingsList, bestProposal); } else if (!Utils.MajorityHasAccepted(underlingsList.Count, tasksArray.Length) || aServerExplicitlyRefused) { return(TryViewChange(knownLivingServers)); } return(this.serverView); }