private int SendPrepareMessage(ClientRequest clientRequest)
        {
            int viewNumber;
            int opNumber;
            int commitNumber;

            Uri[] replicasUrls;


            lock (this.replicaState) {
                viewNumber   = this.replicaState.ViewNumber;
                commitNumber = this.replicaState.CommitNumber;
                opNumber     = this.replicaState.IncrementOpNumberNumber();
                this.replicaState.Logger.Add(clientRequest);
                replicasUrls = this.replicaState.ReplicasUrl.ToArray();
            }

            PrepareMessage prepareMessage = new PrepareMessage(
                this.replicaState.ServerId,
                viewNumber,
                clientRequest,
                opNumber,
                commitNumber);

            // Wait for (Number backup replicas + the leader) / 2
            int f = this.replicaState.Configuration.Count / 2;

            this.messageServiceClient.RequestMulticast(prepareMessage, replicasUrls, f, -1, true);

            return(opNumber);
        }
        public IResponse VisitPrepareMessage(PrepareMessage prepareMessage)
        {
            if (prepareMessage.ViewNumber < this.replicaState.ViewNumber)
            {
                return(null);
            }
            if (this.replicaState.OpNumber >= prepareMessage.OpNumber)
            {
                return(new PrepareOk(this.replicaState.ServerId, this.replicaState.ViewNumber, prepareMessage.OpNumber));
            }

            // It must wait for previous messages.
            while (this.replicaState.OpNumber != (prepareMessage.OpNumber - 1))
            {
                if (prepareMessage.ViewNumber < this.replicaState.ViewNumber)
                {
                    return(null);
                }
                if (this.replicaState.OpNumber >= prepareMessage.OpNumber - 1)
                {
                    return(new PrepareOk(this.replicaState.ServerId, this.replicaState.ViewNumber, prepareMessage.OpNumber));
                }
                this.replicaState.HandlersPrepare.WaitOne();
            }

            int opNumber;
            int replicaView;

            lock (this.replicaState) {
                replicaView = this.replicaState.ViewNumber;
                opNumber    = this.replicaState.IncrementOpNumberNumber();
                this.replicaState.Logger.Add(prepareMessage.ClientRequest);
            }

            // Notify all threads that are waiting for new prepare messages
            this.replicaState.HandlersPrepare.Set();
            this.replicaState.HandlersPrepare.Reset();
            this.replicaState.HandlersCommits.Set();
            this.replicaState.HandlersCommits.Reset();

            return(new PrepareOk(this.replicaState.ServerId, replicaView, opNumber));
        }
Пример #3
0
        /// <summary>
        /// SOLID:
        ///  Falhas:
        ///  - Apenas escreve no ecrã. E se quisermos escrever num ficheiro?
        ///  - Apenas escreve "Olá MUndo"...e se quisermos escrever outras coisa?
        ///  - E se quisermos a acrescentar mais "features"?
        ///  - ????
        /// </summary>
        static void Main1()
        {
            //1
            //Console.WriteLine("Ola Mundo");
            //2
            IGetMessage mensagem = new ConsoleGetMessage();
            ITextWriter writer   = new ConsoleTextWriter();


            //auxiliar
            PrepareMessage msg = new PrepareMessage(mensagem, writer);

            msg.Go();

            ITextWriter    writer2 = new FileTextWriter();
            PrepareMessage msg2    = new PrepareMessage(mensagem, writer2);

            msg2.Go();

            Console.ReadKey();
        }
Пример #4
0
 public IResponse VisitPrepareMessage(PrepareMessage prepareMessage)
 {
     return(this.WaitNormalState(prepareMessage));
 }
Пример #5
0
        public static void Handle(
            PrepareMessage message,
            Replica replica,
            byte[] replicaSecret,
            out int[] block,
            out string secretShare,
            out Dictionary <int, uint> childSecretHashes,
            out uint secretHash,
            Dictionary <int, CancellationTokenSource> secretShareMessageTokenSources)
        {
            block = message.Block;
            var requestCounterViewNumber = message.RequestCounterViewNumber;

            replica.Tee.VerifyCounter(
                replica.PrimaryReplica.PublicKey,
                requestCounterViewNumber,
                replicaSecret,
                out secretShare,
                out childSecretHashes,
                out secretHash);

            if (replica.ChildReplicas.Any())
            {
                foreach (var childReplica in replica.ChildReplicas)
                {
                    var tokenSource = new CancellationTokenSource();

                    Task.Delay(5000, tokenSource.Token)
                    .ContinueWith(t =>
                    {
                        if (!t.IsCanceled)
                        {
                            // we send message about a suspected replica to the primary replica
                            Network.EmulateLatency();

                            replica.PrimaryReplica.SendMessage(
                                new SuspectMessage
                            {
                                ReplicaId = childReplica.Id
                            });
                        }
                    });

                    secretShareMessageTokenSources.Add(childReplica.Id, tokenSource);
                }
            }
            else
            {
                // we send a message with a secret share to the parent replica
                Network.EmulateLatency();

                replica.ParentReplica.SendMessage(
                    new SecretShareMessage
                {
                    ReplicaId           = replica.Id,
                    ReplicaSecretShares = new Dictionary <int, string> {
                        { replica.Id, secretShare }
                    }
                });

                Log(replica, "Send a secret to the parent replica (ParentReplicaId: {0})", replica.ParentReplica.Id);
            }
        }