예제 #1
0
        internal override ReplyData HandleRequest(RequestData requestData, int requestNum)
        {
            Random random     = new Random();
            int    delayValue = random.Next(minDelay, maxDelay);

            Thread.Sleep(delayValue);

            while (freezed || requestNum < currentReq)
            {
                Thread.Sleep(200);
            }

            Utils.Print("[*] SMRServer: Handle Request.");
            if (CheckOldMsg(requestData))
            {
                return(new DiscardedMsgReply(requestData.RequestId));
            }
            if (CheckOldView(requestData))
            {
                return(new ViewProposal(viewManager.GetView(), ServerData));
            }

            holdbackQueue.Add(requestData.RequestId, requestData);
            Utils.Print(" [*] SMR Server: Added to Holdback Queue.", verbose: Verbose);
            Utils.Print($" [*] SMR Server: Request ID: {requestData.RequestId}.", verbose: Verbose);

            View       view       = viewManager.GetView();
            string     leaderUId  = view.ManagerUId;
            ServerData leaderData = view.Find(leaderUId);

            if (leaderData.Equals(ServerData)) // As the View Leader.
            {
                int requestId = requestData.RequestId;
                Utils.Print($" [*] SMR Server Sequencer: Request ID: {requestId}.", verbose: Verbose);

                //If the message received is not the following message of the previously received
                //from the same Client, the message is added to the hold back list, to ensure FIFO
                //ordering.
                int lastClientMessageId = mIdTable[requestData.ClientId];
                Utils.Print($" [*] SMR Server Sequencer: Last Client Request ID: {lastClientMessageId}.", verbose: Verbose);
                if (requestId > lastClientMessageId + 1)
                {
                    holdbackQueueSequencer.Add(requestId, requestData);
                    return(null);
                }
                SendTotalOrder(requestData.ClientId, requestId);
                return(null);
            }
            CheckDeliveryQueue();
            return(null);
        }
예제 #2
0
        internal ReplyData Take(RequestData requestData)
        {
            ViewManager viewM      = viewManager;
            View        view       = viewM.GetView();
            ServerData  leaderData = view.Find(view.ManagerUId);

            if (leaderData.Equals(ServerData)) // As the View Leader.
            {
                receiveTakeTupleFromLeader.Reset();
                List <List <DIDATuple> > serversMatchingTuples = new List <List <DIDATuple> >();
                List <ServerData>        replicasList          = viewManager.GetKnownReplicas();

                Utils.Print($" [*] SMR Server Leader: Calling {replicasList.Count()} servers.", verbose: Verbose);
                foreach (ServerData serverData in replicasList)
                {
                    if (!serverData.Equals(leaderData))
                    {
                        string            serverProxyURL = $"tcp://{serverData.ServerURL}/{serverData.ServerName}";
                        ISMRServerService serverProxy    = (ISMRServerService)Activator.GetObject(typeof(ISMRServerService), serverProxyURL);
                        try
                        {
                            List <DIDATuple> matchingTuples = serverProxy.SendMatchingTuples(requestData.TupleData);
                            serversMatchingTuples.Add(matchingTuples);
                        }
                        catch (SocketException)
                        {
                            viewManager.TryViewChange(viewManager.GetKnownReplicas());
                        }
                    }
                }
                serversMatchingTuples.Add(GetMatchingTuples(requestData.TupleData));
                PrintTuplesListsList(serversMatchingTuples);

                DIDATuple takeTuple = GetRandomIntersectedTuple(serversMatchingTuples);
                if (takeTuple == null)
                {
                    return(new NoTupleFoundReply(requestData.RequestId));
                }

                Utils.Print($" [*] SMR Server Leader: Taking {takeTuple}.", verbose: Verbose);

                // Removed tuple from all replicas.
                foreach (ServerData serverData in replicasList)
                {
                    string            serverProxyURL        = $"tcp://{serverData.ServerURL}/{serverData.ServerName}";
                    ISMRServerService serverProxy           = (ISMRServerService)Activator.GetObject(typeof(ISMRServerService), serverProxyURL);
                    RequestData       leaderTakeRequestData = new RequestData(0, 0, "", "", takeTuple, EOperationType.Take);
                    try
                    {
                        serverProxy.ReceiveTakeTuple(leaderTakeRequestData);
                    }
                    catch (SocketException)
                    {
                        viewManager.TryViewChange(viewManager.GetKnownReplicas());
                    }
                }

                object toRemove = takeTuple;
                if (tupleSpace.TryTake(out toRemove))
                {
                    return(new TupleReply(requestData.RequestId, takeTuple));
                }
                else
                {
                    return(new NoTupleFoundReply(requestData.RequestId)); // Should be impossible to execute this else.
                }
            }
            // As a follower.
            else
            {
                receiveTakeTupleFromLeader.WaitOne(); // Waits for the signal of when the Take Tuple arrives.
                // After receiving the Tuple from the Leader, for the Take Operation.
                DIDATuple takeTuple = takeTupleFromLeader.TupleData;
                Utils.Print($" [*] SMR Server: Taking {takeTuple}.", verbose: Verbose);
                if (takeTuple == null)
                {
                    return(new NoTupleFoundReply(requestData.RequestId));
                }
                object toRemove = takeTuple;
                if (tupleSpace.TryTake(out toRemove))
                {
                    return(new TupleReply(requestData.RequestId, takeTuple));
                }
                else
                {
                    return(new NoTupleFoundReply(requestData.RequestId)); // Should be impossible to execute this else.
                }
                // Add send Leader an Ack.
            }
        }