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); }
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. } }