예제 #1
0
 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();
 }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }