Пример #1
0
        /// <summary>
        /// Callback function for the phase 1 of the take operation.
        /// </summary>
        /// <param name="result">Async calback result.</param>
        public void Take1Callback(IAsyncResult result)
        {
            RemoteAsyncDelegate del = (RemoteAsyncDelegate)((AsyncResult)result).AsyncDelegate;

            // Retrieve results.
            TSpaceMsg response = del.EndInvoke(result);

            //Console.WriteLine("take1" + response);

            if (!ValidView(response))
            {
                return;
            }


            // Stores the list of matching tuples
            // and the RequestID of the server that answered
            if (response.Code.Equals("OK"))
            {
                // Tuples have to be added before the acks are incremented
                lock (MatchingTuples) {
                    MatchingTuples.Add(new List <ITuple>(response.Tuples));

                    Interlocked.Increment(ref AcksCounter);
                }
                if (verbose)
                {
                    Console.WriteLine("Response:");
                    Console.WriteLine(response);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Adds a tuple to the distributed tuple space.
        /// </summary>
        /// <param name="tuple">Tuple to be added.</param>
        public void Add(ITuple tuple)
        {
            if (View.Count == 0)
            {
                Console.WriteLine("No tuple space servers available.");
                return;
            }

            // Create request message
            TSpaceMsg message = new TSpaceMsg();

            message.Code      = "add";
            message.Tuple     = tuple;
            message.RequestID = ClientID + "_" + (++SequenceNumber);
            message.MsgView   = GetCurrentView();


            //Clear acks
            AcksCounter = 0;

            // Create local callback
            AsyncCallback remoteCallback = new AsyncCallback(AddCallback);

            // Repeat request until all replicas have acknowledged receipt
            while (AcksCounter < View.Count)
            {
                //Send multicast message to all members of the view
                this.Multicast(message, remoteCallback);
            }

            Console.WriteLine("Add " + (++AddCounter) + ": OK");
        }
Пример #3
0
        private void ReadCallback(IAsyncResult result)
        {
            RemoteAsyncDelegate del = (RemoteAsyncDelegate)((AsyncResult)result).AsyncDelegate;

            // Retrieve results.
            TSpaceMsg response = del.EndInvoke(result);


            if (!ValidView(response))
            {
                return;
            }

            // Stores the tuple returned
            // and the OperationID of the server that answered
            if (response.Code.Equals("OK"))
            {
                if (response.Tuple != null)
                {
                    lock (LockRef)
                    {
                        Tuple = response.Tuple;
                    }
                    if (verbose)
                    {
                        Console.WriteLine("Response:");
                        Console.WriteLine(response);
                    }
                }

                Interlocked.Increment(ref AcksCounter);
            }
        }
Пример #4
0
        /****************************************************************
        *                   CALLBACK FUNCTIONS
        ****************************************************************/
        private void PropesedSeqCallback(IAsyncResult result)
        {
            RemoteAsyncDelegate del = (RemoteAsyncDelegate)((AsyncResult)result).AsyncDelegate;

            // Retrieve results.
            TSpaceMsg response = del.EndInvoke(result);

            if (!ValidView(response))
            {
                return;
            }


            if (response.Code.Equals("proposedSeq"))
            {
                //Console.WriteLine("Proposed Seq");

                lock (ProposedSeq)
                {
                    // Store porposed sequence number
                    ProposedSeq.Add(response.SequenceNumber);
                    Interlocked.Increment(ref AcksCounter);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Makes an async remote invocation of TSpaceServer.ProcessRequest
        /// </summary>
        /// <param name="message">Argument of the ProcessRequest method.</param>
        /// <param name="asyncCallback">Callback function of the remote call.</param>
        private void Multicast(TSpaceMsg message, AsyncCallback asyncCallback)
        {
            if (CheckNeedUpdateView())
            {
                Console.WriteLine("Update to " + GetCurrentView());
                message.MsgView = GetCurrentView();
            }

            //Console.WriteLine("Sending " + message.Code + " in view " + message.MsgView);

            RemoteAsyncDelegate remoteDel;

            foreach (ITSpaceServer server in View)
            {
                // Create delegate for remote method
                remoteDel = new RemoteAsyncDelegate(server.ProcessRequest);
                try
                {
                    // Call remote method
                    remoteDel.BeginInvoke(message, asyncCallback, null);
                }catch (Exception e)
                {
                    Console.WriteLine("Failed to send");
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Adds a tuple to the distributed tuple space.
        /// </summary>
        /// <param name="tuple">Tuple to be added.</param>
        public void Add(ITuple tuple)
        {
            if (View.Count == 0)
            {
                Console.WriteLine("No tuple space servers available.");
                return;
            }
            // Create message
            TSpaceMsg request = new TSpaceMsg();

            request.Code  = "add";
            request.Tuple = tuple;
            // Create unique message identifier
            request.OperationID = ClientID + "_" + (OperationCounter++);
            // Get the sequence number of the request in the view
            request.SequenceNumber = GetSequenceNumber(request.OperationID);
            request.RequestID      = ClientID + "_" + (RequestCounter++);

            request.MsgView = GetCurrentView();

            AsyncCallback remoteCallback = new AsyncCallback(AcksCallback);


            // Clear acks count
            AcksCounter = 0;

            // Repeat until all replicas have acknowledged receipt
            while (AcksCounter < View.Count)
            {
                // Send request to all replicas in the view
                this.Multicast(request, remoteCallback);
            }
            Console.WriteLine("Add " + (++AddCounter) + ": OK");
        }
Пример #7
0
        /// <summary>
        /// Callback function for the read operation.
        /// </summary>
        /// <param name="result">Async callback result.</param>
        public void ReadCallback(IAsyncResult result)
        {
            RemoteAsyncDelegate del = (RemoteAsyncDelegate)((AsyncResult)result).AsyncDelegate;

            // Retrieve results.
            TSpaceMsg response = del.EndInvoke(result);

            if (!ValidView(response))
            {
                return;
            }

            // Stores the tuple returned
            // and the RequestID of the server that answered
            if (response.Code.Equals("OK"))
            {
                lock (LockRef)
                {
                    if (response.Tuple != null)
                    {
                        Tuple = response.Tuple;
                    }
                }
                IncrementAcksCounter(response.RequestID);
            }
        }
Пример #8
0
        public TSpaceMsg ProcessRequest(TSpaceMsg msg)
        {
            TSpaceMsg response;

            //Console.WriteLine("started processing");
            //Console.WriteLine(msg);

            TSMan.Processing();

            response = SMRProcessRequest(msg);

            lock (TSpaceManager.ProcessedRequests)
            {
                if (response.Code != "Repeated" && response.Code != "badView" && TSpaceManager.ProcessedRequests.Contains(msg.RequestID))
                {
                    TSpaceManager.ProcessedRequests.UpdateResponse(msg.RequestID, response);
                    //Console.WriteLine("SAVED THIS TRASH: " + response.ToString());
                }
            }

            TSMan.FinishedProcessing();


            //Console.WriteLine("finished processing");
            //Console.WriteLine("RESPONSE:" + response);

            return(response);
        }
Пример #9
0
        /// <summary>
        /// Makes an async remote invocation of TSpaceServer.ProcessRequest
        /// </summary>
        /// <param name="message">Argument of the ProcessRequest method.</param>
        /// <param name="asyncCallback">Callback function of the remote call.</param>
        private void Multicast(TSpaceMsg message, AsyncCallback asyncCallback)
        {
            //Never happens in this implementation
            if (message.Code.Equals("badView") && message.MsgView.ID > TSMan.ServerView.ID)
            {
                AcksCounter = 0;
            }

            List <ITSpaceServer> servers = TSMan.ServerView.GetProxys(TSMan.URL);
            RemoteAsyncDelegate  remoteDel;

            foreach (ITSpaceServer server in servers)
            {
                // Create delegate for remote method
                remoteDel = new RemoteAsyncDelegate(server.ProcessRequest);
                try
                {
                    // Call remote method
                    remoteDel.BeginInvoke(message, asyncCallback, null);
                }
                catch (Exception)
                {
                    Console.WriteLine("Failed to send");
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Returns a tuple from the distributed tuple space, deleting it.
        /// </summary>
        /// <param name="template">Template of the requested tuple.</param>
        /// <returns></returns>
        public ITuple Take(ITuple template)
        {
            if (View.Count == 0)
            {
                Console.WriteLine("No tuple space servers available.");
                return(null);
            }

            /*------------------------------------------------
            *   Phase 1: Selecting the tuple to be removed
            *  ------------------------------------------------*/

            ITuple selectedTuple = null;

            // Repeat phase 1 until all replicas return at least
            // one common matching tuple
            while (selectedTuple == null)
            {
                Console.WriteLine("Take 1: " + SequenceNumber);
                selectedTuple = this.Take1(template);
            }

            Console.WriteLine("Take: Phase 1 completed");


            /*------------------------------------------------
            *   Phase 2: Removing the selected tuple
            *  ------------------------------------------------*/
            TSpaceMsg message = new TSpaceMsg();

            message.Code      = "take2";
            message.Tuple     = selectedTuple;
            message.ProcessID = ClientID.ToString();
            message.RequestID = ClientID + "_" + (++SequenceNumber);
            message.MsgView   = GetCurrentView();


            // Create local callback.
            AsyncCallback remoteCallback = new AsyncCallback(AddCallback);

            //Clear acks
            ActiveOperations.Add(message.RequestID);
            AcksCounter = 0;

            //Repeat until all replicas have acknowledged deletion
            while (AcksCounter < Quorum())
            {
                // Send multicast request to remove tuples to all members of the view
                this.Multicast(message, remoteCallback);
            }
            ActiveOperations.Remove(message.RequestID);

            Console.WriteLine("Take: Phase 2 completed");

            Console.WriteLine("Take " + (++TakeCounter) + ": OK");
            return(message.Tuple);
        }
Пример #11
0
 public void UpdateResponse(String id, TSpaceMsg response)
 {
     foreach (LogEntry entry in Log)
     {
         if (entry.Request.RequestID == id)
         {
             entry.Response = response;
         }
     }
 }
Пример #12
0
 public bool ValidView(TSpaceMsg msg)
 {
     lock (ServerView)
     {
         if (msg.MsgView == null)
         {
             Console.WriteLine("NO VIEW SENT WITH MSG");
         }
         return(msg.MsgView.ID == ServerView.ID);
     }
 }
Пример #13
0
        public TSpaceMsg CreateBadViewReply(TSpaceMsg msg)
        {
            TSpaceMsg response = new TSpaceMsg
            {
                Code        = "badView",
                ProcessID   = URL,
                OperationID = msg.OperationID,
                RequestID   = msg.RequestID,
                MsgView     = GetTotalView()
            };

            return(response);
        }
Пример #14
0
        private static void AddMessageToQueue(TSpaceMsg msg)
        {
            lock (MessageQueue)
            {
                Message newMessage = new Message();
                newMessage.ProcessID      = msg.ProcessID;
                newMessage.SequenceNumber = SequenceNumber;
                newMessage.Deliverable    = false;
                newMessage.MessageID      = msg.OperationID;

                // Add message to queue
                MessageQueue.Add(newMessage);
                MessageQueue.Sort();
            }
        }
Пример #15
0
        /***********************************************************
        *                  CALLBACK FUNCTIONS
        ***********************************************************/

        /// <summary>
        /// Callback function for the acknowledgements.
        /// </summary>
        /// <param name="result">Async callback result.</param>
        public void AddCallback(IAsyncResult result)
        {
            RemoteAsyncDelegate del = (RemoteAsyncDelegate)((AsyncResult)result).AsyncDelegate;
            // Retrieve results.
            TSpaceMsg response = del.EndInvoke(result);


            if (!ValidView(response))
            {
                return;
            }

            if (response.Code.Equals("ACK"))
            {
                IncrementAcksCounter(response.RequestID);
            }
        }
Пример #16
0
        /// <summary>
        /// Callback function for the acknowledgements.
        /// </summary>
        /// <param name="result">Async call result.</param>
        private void AcksCallback(IAsyncResult result)
        {
            RemoteAsyncDelegate del = (RemoteAsyncDelegate)((AsyncResult)result).AsyncDelegate;
            // Retrieve results.
            TSpaceMsg response = del.EndInvoke(result);

            if (!ValidView(response))
            {
                return;
            }


            if (response.Code.Equals("ACK"))
            {
                Interlocked.Increment(ref AcksCounter);
            }
        }
Пример #17
0
        /****************************************************************
        *                     AUX FUNCTIONS / CLASSES
        ****************************************************************/

        /// <summary>
        /// Determines the agreed sequence number of a message
        /// </summary>
        /// <param name="id">Message OperationID</param>
        /// <returns>Agreed sequence number</returns>
        private int GetSequenceNumber(string id)
        {
            //Console.WriteLine("Message " + id + " : request proposed sequence number");

            // Create request message
            TSpaceMsg message = new TSpaceMsg();

            message.Code        = "proposeSeq";
            message.OperationID = id;
            message.ProcessID   = ClientID.ToString();
            message.RequestID   = ClientID + "_" + (RequestCounter++);
            ActiveOperations.Add(message.RequestID);
            message.SequenceNumber = -1;
            message.MsgView        = GetCurrentView();


            // Create local callback
            AsyncCallback asyncCallback = new AsyncCallback(PropesedSeqCallback);

            // Clear proposed sequence number for previous messages
            lock (ProposedSeq)
            {
                AcksCounter = 0;
                ProposedSeq.Clear();
            }

            // Send message to all replicas until all have proposed a sequence number
            while (AcksCounter < Quorum())
            {
                this.Multicast(message, asyncCallback);
            }

            int agreedSeq;

            lock (ProposedSeq)
            {
                // Agreed sequence number = highest proposed sequence number
                agreedSeq = ProposedSeq.Max();
            }

            Console.WriteLine("Message " + message.OperationID + " (agreedSeq = " + agreedSeq + ")");
            // Remove operation from active operations
            ActiveOperations.Remove(message.RequestID);
            return(agreedSeq);
        }
Пример #18
0
        public void Add(TSpaceMsg request)
        {
            LogEntry entry = new LogEntry
            {
                Request = request
            };

            if (!request.Code.Equals("proposeSeq"))
            {
                entry.Agreed = true;
            }
            else
            {
                entry.Agreed = false;
            }


            Log.Add(entry);
        }
Пример #19
0
        public TSpaceMsg ProcessRequest(TSpaceMsg msg)
        {
            TSpaceMsg response;
            TSMan.Processing();

            response = XLProcessRequest(msg);

            lock (TSpaceManager.ProcessedRequests)
            {
                if (response.Code != "Repeated" && response.Code != "badView" && TSpaceManager.ProcessedRequests.Contains(msg.RequestID))
                {
                    TSpaceManager.ProcessedRequests.UpdateResponse(msg.RequestID, response);
                }
            }

            TSMan.FinishedProcessing();
            
            return response;
        }
Пример #20
0
        /// <summary>
        /// Process a request
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public TSpaceMsg ProcessRequest(TSpaceMsg msg)
        {
            TSpaceMsg response;

            //Acquires writers/readers lock
            TSMan.Processing();

            response = SMRProcessRequest(msg);

            lock (TSpaceAdvManager.ProcessedRequests)
            {
                if (response.Code != "Repeated" && response.Code != "badView" && TSpaceAdvManager.ProcessedRequests.Contains(msg.RequestID))
                {
                    TSpaceAdvManager.ProcessedRequests.UpdateResponse(msg.RequestID, response);
                }
            }

            //Releases writers/readers lock
            TSMan.FinishedProcessing();

            return(response);
        }
Пример #21
0
        public bool ValidView(TSpaceMsg msg)
        {
            lock (ServerView){
                if (msg.MsgView == null)
                {
                    return(false);
                }

                if (msg.Code.Equals("badView") && msg.MsgView.ID > ServerView.ID)
                {
                    InvalidView = true;
                    SuggestView(msg.MsgView);
                    return(false);
                }

                if (msg.MsgView.ID < ServerView.ID)
                {
                    return(false);
                }
            }

            return(true);
        }
Пример #22
0
        private void PropesedSeqCallback(IAsyncResult result)
        {
            RemoteAsyncDelegate del = (RemoteAsyncDelegate)((AsyncResult)result).AsyncDelegate;

            // Retrieve results.
            TSpaceMsg response = del.EndInvoke(result);

            if (response == null ||
                (response.Code.Equals("badView") && response.MsgView.ID > TSMan.ServerView.ID))
            {
                return;
            }


            if (response.Code.Equals("proposedSeq"))
            {
                lock (ProposedSeq)
                {
                    // Store porposed sequence number
                    ProposedSeq.Add(response.SequenceNumber);
                    Interlocked.Increment(ref AcksCounter);
                }
            }
        }
Пример #23
0
        /// <summary>
        /// Returns a tuple from the distributed tuple space, deleting it.
        /// </summary>
        /// <param name="template">Template of the tuple requested</param>
        /// <returns>Tuple matching the template</returns>
        public ITuple Take(ITuple template)
        {
            if (View.Count == 0)
            {
                Console.WriteLine("No tuple space servers available.");
                return(null);
            }
            // Create message

            TSpaceMsg request = new TSpaceMsg();

            request.Code  = "take1";
            request.Tuple = template;


            // Create remote callback
            AsyncCallback remoteCallback = new AsyncCallback(ReadCallback);

            // Clear response from last request
            lock (LockRef)
            {
                Tuple = null;
            }

            // Repeat until one matching tuple is found
            while (true)
            {
                // Create unique message identifier
                request.OperationID = ClientID + "_" + (OperationCounter++);

                // Get the sequence number of the request in the view
                request.SequenceNumber = this.GetSequenceNumber(request.OperationID);

                // Create unique identifier for the round
                request.RequestID = ClientID + "_" + (RequestCounter++);

                request.MsgView = GetCurrentView();



                //Clear acks from last request
                AcksCounter = 0;

                // Repeat untill all replicas have answered
                while (AcksCounter < View.Count)
                {
                    // Send take request to all members of the view
                    this.Multicast(request, remoteCallback);
                }


                // Return if there is a match
                // Repeat otherwise
                lock (LockRef)
                {
                    if (Tuple != null)
                    {
                        break;
                    }
                }
            }

            Console.WriteLine("Take " + (++TakeCounter) + ": OK");
            return(Tuple);
        }
Пример #24
0
        /// <summary>
        /// Determines the agreed sequence number of a message
        /// </summary>
        /// <param name="id">Message OperationID</param>
        /// <returns>Agreed sequence number</returns>
        private int GetSequenceNumber(string id, string suspectDead)
        {
            Monitor.Enter(SequenceNumberLock);

            //Console.WriteLine("Message " + id + " : request proposed sequence number");

            // Create request message
            TSpaceMsg message = new TSpaceMsg();

            message.Code        = "proposeSeq";
            message.OperationID = id;
            // Replace ID with server url
            message.ProcessID      = TSMan.URL;
            message.RequestID      = message.ProcessID + "_" + (RequestCounter++);
            message.SequenceNumber = -1;

            message.SuspectedDead = suspectDead;


            // Create local callback
            AsyncCallback asyncCallback = new AsyncCallback(PropesedSeqCallback);

            // Clear proposed sequence number for previous messages
            lock (ProposedSeq)
            {
                AcksCounter = 1;
                ProposedSeq.Clear();

                // Add my proposal
                lock (MessageQueue)
                {
                    Interlocked.Increment(ref SequenceNumber);
                }
                ProposedSeq.Add(SequenceNumber);
                AddMessageToQueue(message);
            }

            // Send message to all replicas until all have proposed a sequence number
            while (AcksCounter < TSMan.Quorum(TSMan.ServerView.Count))
            {
                if (message.MsgView != TSMan.ServerView)
                {
                    AcksCounter = 1;
                    ProposedSeq.Clear();
                    ProposedSeq.Add(SequenceNumber);
                    message.MsgView = TSMan.ServerView;
                }
                this.Multicast(message, asyncCallback);
            }

            int agreedSeq;

            lock (ProposedSeq)
            {
                // Agreed sequence number = highest proposed sequence number
                agreedSeq = ProposedSeq.Max();
            }


            Console.WriteLine("Message " + message.OperationID + " (agreedSeq = " + agreedSeq + ")");

            Monitor.Exit(SequenceNumberLock);
            //UpdateMessage(id, agreedSeq);

            return(agreedSeq);
        }
Пример #25
0
        public TSpaceMsg SMRProcessRequest(TSpaceMsg msg)
        {
            TSMan.CheckFreeze();

            TSMan.CheckDelay();

            lock (AggredOperations)
            {
                if (msg.Code != "proposeSeq")
                {
                    AggredOperations[msg.OperationID] = msg.SequenceNumber;
                }
                else
                {
                    //Console.WriteLine("Not Agreed: " + msg.OperationID);
                }
            }

            TSpaceMsg response = new TSpaceMsg
            {
                ProcessID   = TSMan.URL,
                OperationID = msg.OperationID,
                RequestID   = msg.RequestID,
                MsgView     = TSMan.GetTotalView()
            };

            // Verifying View! Wrong view sends updated view
            if (!TSMan.ValidView(msg))
            {
                Console.WriteLine("Wrong View ( s = " + TSMan.ServerView.ID + "; c = " + msg.MsgView.ID + " )");
                return(TSMan.CreateBadViewReply(msg));
            }

            lock (TSpaceAdvManager.ProcessedRequests)
            {
                // Check if request as already been processed
                if (TSpaceAdvManager.ProcessedRequests.Contains(msg.RequestID))
                {
                    // Check if it was processed in a previous viwew
                    if (TSpaceAdvManager.ProcessedRequests.GetByKey(msg.RequestID).Request.MsgView.ID < TSMan.ServerView.ID)
                    {
                        //Console.WriteLine(TSMan.ServerView.ID);
                        TSpaceAdvManager.ProcessedRequests.UpdateView(msg.RequestID, TSMan.ServerView);
                        TSpaceMsg resp = TSpaceAdvManager.ProcessedRequests.GetByKey(msg.RequestID).Response;
                        if (resp == null)
                        {
                            Console.WriteLine("NULL RESPONSE SAVED");
                            return(null);
                        }

                        return(resp);
                    }
                    else
                    {
                        response.Code = "Repeated";
                        return(response);
                    }
                }
                Console.WriteLine("Starting processing of request " + msg.RequestID);

                // Add sequence number of request to processed requests

                TSpaceAdvManager.ProcessedRequests.Add(msg);
            }

            string command = msg.Code;

            Message update = null;

            // Sequence number proposal request
            if (command.Equals("proposeSeq"))
            {
                lock (AggredOperations)
                {
                    //Already was executed corresponsing operation
                    if (AggredOperations.ContainsKey(msg.OperationID))
                    {
                        response.Code           = "proposedSeq";
                        response.SequenceNumber = AggredOperations[msg.OperationID];
                        return(response);
                    }


                    lock (MessageQueue)
                    {
                        // Increment sequence number
                        Interlocked.Increment(ref SequenceNumber);
                    }
                    response.SequenceNumber = SequenceNumber;
                    response.Code           = "proposedSeq";
                    AddMessageToQueue(msg);
                }

                Console.WriteLine("Proposing (id = " + msg.OperationID + "; seq = " + response.SequenceNumber + ")");

                return(response);
            }

            // Message with agreed sequence number
            else
            {
                //Update message queue with agreed seq number
                update = UpdateMessage(msg.OperationID, msg.SequenceNumber);
                if (update == null)
                {
                    Console.WriteLine("Err: operation message not in queue");
                    //response.Code = "Err";
                }
            }


            //Wait for the message head of queue
            Monitor.Enter(MessageQueue);
            while (MessageQueue.Count == 0 || !MessageQueue[0].MessageID.Equals(msg.OperationID))
            {
                TSMan.FinishedProcessing();
                Monitor.Wait(MessageQueue, 500);
                TSMan.Processing();
            }
            Monitor.Exit(MessageQueue);


            Console.WriteLine("Execute operation " + msg.OperationID + ": code = " + command);

            // Execute the operation
            if (TSMan.Verbose)
            {
                Console.WriteLine(msg);
            }

            switch (command)
            {
            case "add":
                lock (TakeLock)
                {
                    if (msg.Tuple == null)
                    {
                        response.Code = "ERR";
                        break;
                    }

                    TSMan.TSpace.Add(msg.Tuple);
                    response.Code = "ACK";
                    break;
                }

            case "read":
                if (msg.Tuple == null)
                {
                    response.Code = "ERR";
                    break;
                }
                response.Tuple = TSMan.TSpace.Read(msg.Tuple);
                response.Code  = "OK";
                if (response.Tuple == null)
                {
                    Console.WriteLine("Match not Found");
                }
                break;

            case "take1":
                lock (TakeLock)
                {
                    if (msg.Tuple == null)
                    {
                        response.Code = "ERR";
                        break;
                    }

                    // Get matching tuple
                    response.Tuple = TSMan.TSpace.Read(msg.Tuple);
                    response.Code  = "OK";
                    if (response.Tuple != null)
                    {
                        // Delete it
                        TSMan.TSpace.Take2(response.Tuple);
                    }
                }
                response.Code = "OK";
                break;

            case "take2":
                Console.WriteLine("Current Tuple Space not in XL mode");
                response.Code = "ERR";
                break;


            // Operation exclusive of the XL Tuple Space
            case "releaseLocks":

                lock (TakeLock)
                    response.Code = "ERR";
                Console.WriteLine("Current Tuple Space not in XL mode");
                break;

            default:
                Console.WriteLine("Invalid command.");
                break;
            }


            RemoveFromQueue(msg.OperationID);

            return(response);
        }
Пример #26
0
        public TSpaceMsg XLProcessRequest(TSpaceMsg msg)
        {

            TSMan.CheckFreeze();
            TSMan.CheckDelay();

            TSpaceMsg response = new TSpaceMsg
            {
                ProcessID = TSMan.URL,
                RequestID = msg.RequestID,
                MsgView = TSMan.GetTotalView()
            };

            // Verifying View! Wrong view sends updated view
            if (!TSMan.ValidView(msg))
            {
                //Console.WriteLine("client:" +  msg.MsgView.ToString() + "server:" +TSMan.GetTotalView().ToString());
                Console.WriteLine("Wrong View ( s = " + TSMan.ServerView + "; c = " + msg.MsgView + " )");
                return TSMan.CreateBadViewReply(msg);
            }

            if (TSMan.Verbose)
                Console.WriteLine(msg);


            lock (TSpaceManager.ProcessedRequests)
            {
                // Check if request as already been processed
                if (TSpaceManager.ProcessedRequests.Contains(msg.RequestID))
                {
                    LogEntry Temp = TSpaceManager.ProcessedRequests.GetByKey(msg.RequestID);
                    // Check if it was processed in a previous viwew
                    if (Temp.Request.MsgView.ID < TSMan.ServerView.ID ||
                        (Temp.Response != null && Temp.Response.ProcessID != TSMan.URL))
                    {
                        //Console.WriteLine("Processed in previous view");
                        
                        TSpaceMsg resp = TSpaceManager.ProcessedRequests.GetByKey(msg.RequestID).Response;
                        
                        if (resp == null)
                        {
                            Console.WriteLine("NULL RESPONSE SAVED");
                            return null;
                        }

                        resp.MsgView = TSMan.ServerView;

                        TSpaceManager.ProcessedRequests.UpdateView(msg.RequestID, TSMan.ServerView);
                        TSpaceManager.ProcessedRequests.UpdateResponse(msg.RequestID, resp);


                        //Console.WriteLine(resp);
                        return resp;
                    }
                    else
                    {
                        
                        //Console.WriteLine("repeated");
                        response.Code = "Repeated";
                        
                        return response;
                    }

                }
                //Console.WriteLine("Starting processing of request " + msg.RequestID);

                // Add sequence number of request to processed requests

                TSpaceManager.ProcessedRequests.Add(msg);

            }

            string command = msg.Code;


            switch (command)
            {
                case "add":
                    TSMan.TSpace.Add(msg.Tuple);
                    response.Code = "ACK";
                    break;

                case "read":
                    response.Tuple = TSMan.TSpace.Read(msg.Tuple);
                    response.Code = "OK";
                    break;

                case "take1":
                    lock (TSLockHandler.Lock)
                    {
                        // find suitable matches for tuple
                        List<ITuple> matches = TSMan.TSpace.Take1(msg.Tuple);
                        // Locks all unlocked and matchable tuples for UserID
                        response.Tuples = TSLockHandler.LockTuples(msg.ProcessID, matches);
                    }
                    
                    response.Code = "OK";
                    break;

                case "take2":
                    lock (TSLockHandler.Lock)
                    {
                        // Deletes tuple
                        TSMan.TSpace.Take2(msg.Tuple);
                        // Unlocks all tuples previously locked under UserID
                        TSLockHandler.UnlockTuples(msg.ProcessID);
                    }
                    response.Code = "ACK";
                    break;

                // Operation exclusive of the XL Tuple Space
                case "releaseLocks":
                    try
                    {
                        TSLockHandler.UnlockTuples(msg.ProcessID);
                        response.Code = "ACK";
                    }
                    catch (InvalidCastException)
                    {
                        Console.WriteLine("Current Tuple Space not in XL mode");
                        response.Code = "ERR";
                    }

                    break;
                default:
                    Console.WriteLine("Invalid command.");
                    break;
            }
            return response;
        }
Пример #27
0
        /// <summary>
        /// Returns a tuple from the distributed tuple space, whithout deleting it.
        /// </summary>
        /// <param name="template">Template of the requested tuple.</param>
        /// <returns></returns>
        public ITuple Read(ITuple template)
        {
            Console.WriteLine("Read started");
            if (View.Count == 0)
            {
                Console.WriteLine("No tuple space servers available.");
                return(null);
            }

            // Create message
            TSpaceMsg request = new TSpaceMsg();

            request.Code  = "read";
            request.Tuple = template;


            AsyncCallback remoteCallback = new AsyncCallback(ReadCallback);

            // Clear responses to previous request
            // Clear previous answers
            lock (LockRef)
            {
                Tuple = null;
            }

            bool matchFound = false;

            while (!matchFound)
            {
                // Create unique id of the request
                request.RequestID = ClientID + "_" + (RequestCounter++);

                // Create unique message identifier
                request.OperationID = ClientID + "_" + (OperationCounter++);

                // Get the sequence number of the request in the view
                request.SequenceNumber = this.GetSequenceNumber(request.OperationID);

                request.MsgView = GetCurrentView();

                AcksCounter = 0;

                // Waits until one replica returns a tuple or
                // all replicas answered that they dont have a match
                while (AcksCounter < View.Count)
                {
                    // Send multicast request to all members of the view
                    this.Multicast(request, remoteCallback);

                    lock (LockRef)
                    {
                        if (Tuple != null)
                        {
                            matchFound = true;
                            break;
                        }
                    }
                }
                lock (LockRef)
                {
                    if (Tuple != null)
                    {
                        matchFound = true;
                    }
                }
            }
            Console.WriteLine("Read " + (++ReadCounter) + ": OK");

            // Return after the first replica answers
            return(Tuple);
        }
Пример #28
0
        /// <summary>
        /// Returns a tuple from the distributed tuple space, whithout deleting it.
        /// </summary>
        /// <param name="template">Template of the requested tuple.</param>
        /// <returns></returns>
        public ITuple Read(ITuple template)
        {
            if (View.Count == 0)
            {
                Console.WriteLine("No tuple space servers available.");
                return(null);
            }

            // Create request message.
            TSpaceMsg message = new TSpaceMsg();

            message.Code    = "read";
            message.Tuple   = template;
            message.MsgView = GetCurrentView();


            // Create local callback.
            AsyncCallback remoteCallback = new AsyncCallback(ReadCallback);

            // Clear previous answers
            lock (LockRef)
            {
                Tuple = null;
            }

            bool matchFound = false;

            while (!matchFound)
            {
                message.RequestID = ClientID + "_" + (++SequenceNumber);
                AcksCounter       = 0;

                // Waits until one replica returns a tuple or
                // all replicas answered that they dont have a match
                while (AcksCounter < View.Count)
                {
                    // Send multicast message to all members of the view.
                    this.Multicast(message, remoteCallback);

                    // Return after first response
                    lock (LockRef)
                    {
                        if (Tuple != null)
                        {
                            matchFound = true;
                            break;
                        }
                    }
                }

                lock (LockRef)
                {
                    if (Tuple != null)
                    {
                        matchFound = true;
                    }
                }
            }

            // Return first response.
            Console.WriteLine("Read " + (++ReadCounter) + ": OK");

            return(Tuple);
        }
Пример #29
0
        public TSpaceMsg SMRProcessRequest(TSpaceMsg msg)
        {
            TSMan.CheckFreeze();

            TSMan.CheckDelay();

            TSpaceMsg response = new TSpaceMsg
            {
                ProcessID   = TSMan.URL,
                OperationID = msg.OperationID,
                RequestID   = msg.RequestID,
                MsgView     = TSMan.GetTotalView()
            };

            //Console.WriteLine("client:" +  msg.MsgView.ToString() + "server:" +TSMan.GetTotalView().ToString());
            // Verifying View! Wrong view sends updated view
            if (!TSMan.ValidView(msg))
            {
                //Console.WriteLine("client:" +  msg.MsgView.ToString() + "server:" +TSMan.GetTotalView().ToString());
                Console.WriteLine("Wrong View ( s = " + TSMan.ServerView + "; c = " + msg.MsgView + " )");
                return(TSMan.CreateBadViewReply(msg));
            }

            lock (TSpaceManager.ProcessedRequests)
            {
                // Check if request as already been processed
                if (TSpaceManager.ProcessedRequests.Contains(msg.RequestID))
                {
                    // Check if it was processed in a previous viwew
                    if (TSpaceManager.ProcessedRequests.GetByKey(msg.RequestID).Request.MsgView.ID < TSMan.ServerView.ID)
                    {
                        //Console.WriteLine(TSMan.ServerView.ID);
                        TSpaceManager.ProcessedRequests.UpdateView(msg.RequestID, TSMan.ServerView);
                        TSpaceMsg resp = TSpaceManager.ProcessedRequests.GetByKey(msg.RequestID).Response;
                        if (resp == null)
                        {
                            Console.WriteLine("NULL RESPONSE SAVED");
                            return(null);
                        }

                        return(resp);
                    }
                    else
                    {
                        //Console.WriteLine("repeated");
                        response.Code = "Repeated";

                        //Console.WriteLine("Repeated message response was:" + TSpaceManager.ProcessedRequests.GetByKey(msg.RequestID).Response);
                        return(response);
                    }
                }
                Console.WriteLine("Starting processing of request " + msg.RequestID);

                // Add sequence number of request to processed requests

                TSpaceManager.ProcessedRequests.Add(msg);
            }

            string command = msg.Code;
            //Console.WriteLine("Processing Request " + command + " (seq = " + msg.RequestID + ")");

            Message update = null;

            // Sequence number proposal request
            if (command.Equals("proposeSeq"))
            {
                Console.WriteLine("Propose request received " + msg.OperationID);
                // Increment sequence number
                Interlocked.Increment(ref SequenceNumber);
                response.SequenceNumber = SequenceNumber;
                response.Code           = "proposedSeq";

                lock (MessageQueue)
                {
                    Message newMessage = new Message();
                    newMessage.ProcessID      = msg.ProcessID;
                    newMessage.SequenceNumber = SequenceNumber;
                    newMessage.Deliverable    = false;
                    newMessage.MessageID      = msg.OperationID;

                    // Add message to queue
                    MessageQueue.Add(newMessage);
                    MessageQueue.Sort();
                }

                Console.WriteLine("Return propose answer" + msg.OperationID);
                return(response);
            }
            // Message with agreed sequence number
            else
            {
                update = UpdateMessage(msg.OperationID, msg.SequenceNumber);
                if (update == null)
                {
                    Console.WriteLine("Err: operation message not in queue");
                    response.Code = "Err";

                    return(response);
                }
            }
            // Wait for message to be in the head of the queue
            Monitor.Enter(MessageQueue);
            while (MessageQueue.Count == 0 || !MessageQueue[0].MessageID.Equals(msg.OperationID))
            {
                //Console.WriteLine("stuck at while");
                Monitor.Wait(MessageQueue);
            }
            Monitor.Exit(MessageQueue);

            Console.WriteLine("Execute operation " + msg.OperationID + ": code = " + command);

            // Execute the operation

            if (TSMan.Verbose)
            {
                Console.WriteLine(msg);
            }



            switch (command)
            {
            case "add":
                lock (TakeLock)
                {
                    if (msg.Tuple == null)
                    {
                        response.Code = "ERR";
                        break;
                    }

                    TSMan.TSpace.Add(msg.Tuple);
                    response.Code = "ACK";
                    break;
                }

            case "read":
                if (msg.Tuple == null)
                {
                    response.Code = "ERR";
                    break;
                }
                response.Tuple = TSMan.TSpace.Read(msg.Tuple);
                response.Code  = "OK";
                if (response.Tuple == null)
                {
                    Console.WriteLine("Match not Found");
                }
                //else
                //Console.WriteLine("Match found");
                break;

            case "take1":
                lock (TakeLock)
                {
                    if (msg.Tuple == null)
                    {
                        response.Code = "ERR";
                        break;
                    }

                    // Get matching tuple
                    response.Tuple = TSMan.TSpace.Read(msg.Tuple);
                    response.Code  = "OK";
                    if (response.Tuple != null)
                    {
                        // Delete it
                        TSMan.TSpace.Take2(response.Tuple);
                    }
                }

                response.Code = "OK";


                break;

            case "take2":
                Console.WriteLine("Current Tuple Space not in XL mode");
                response.Code = "ERR";

                break;


            // Operation exclusive of the XL Tuple Space
            case "releaseLocks":

                lock (TakeLock)
                    response.Code = "ERR";
                Console.WriteLine("Current Tuple Space not in XL mode");

                break;

            default:
                Console.WriteLine("Invalid command.");
                break;
            }

            // Delete processed message from queue
            if (update != null)
            {
                lock (MessageQueue)
                {
                    MessageQueue.Remove(update);
                    Monitor.PulseAll(MessageQueue);
                }
            }
            Console.WriteLine("Return response " + msg.OperationID);

            return(response);
        }
Пример #30
0
        /// <summary>
        /// Executes the phase 1 of the take operation.
        /// </summary>
        /// <param name="template">Template of the requested tuple.</param>
        /// <returns></returns>
        private ITuple Take1(ITuple template)
        {
            // Create request message.
            TSpaceMsg message = new TSpaceMsg();

            message.Code      = "take1";
            message.Tuple     = template;
            message.ProcessID = ClientID.ToString();
            message.RequestID = ClientID + "_" + (++SequenceNumber);
            message.MsgView   = GetCurrentView();


            // Clear responses from previour requests
            lock (MatchingTuples)
            {
                AcksCounter = 0;
                MatchingTuples.Clear();
            }

            // Create local callback.
            AsyncCallback remoteCallback = new AsyncCallback(Take1Callback);

            // Repeat until all replicas have responded
            while (AcksCounter < View.Count)
            {
                //Send multicast take request to all members of the view
                this.Multicast(message, remoteCallback);
            }

            if (AcksCounter > View.Count)
            {
                throw new Exception();
            }
            List <ITuple> intersection;

            lock (MatchingTuples)
            {
                // Select one tuple from the intersection of all matching tuples lists
                intersection = MatchingTuples[0];

                foreach (List <ITuple> tupleList in MatchingTuples)
                {
                    intersection.Intersect(tupleList, new TupleComparator());
                }
            }


            // If intersection = {}
            // Send release locks to all replicas
            if (intersection.Count == 0)
            {
                //Create message
                message.Code      = "releaseLocks";
                message.RequestID = ClientID + "_" + (++SequenceNumber);


                // Clear acks
                AcksCounter = 0;

                // Create remote callback
                remoteCallback = new AsyncCallback(AddCallback);

                // Repeat until all replicas have acknowledged release
                while (AcksCounter < View.Count)
                {
                    //Send multicast take request to all members of the view
                    this.Multicast(message, remoteCallback);
                }

                Console.WriteLine("Take 1: intersection = {}");
                return(null);
            }

            return(intersection[0]);
        }