コード例 #1
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
            ActiveOperations.Add(message.RequestID);
            AcksCounter = 0;

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

            // Repeat request until all replicas have acknowledged receipt
            while (AcksCounter < Quorum())
            {
                //Send multicast message to all members of the view
                this.Multicast(message, remoteCallback);
            }
            ActiveOperations.Remove(message.RequestID);
            Console.WriteLine("Add " + (++AddCounter) + ": OK");
        }
コード例 #2
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);
        }
コード例 #3
0
        public async void BeginOperation(string operationName)
        {
            if (CurrentDocument == null)
            {
                return;
            }

            _oldObjects.Clear();
            _oldObjects.AddRange(CurrentDocument.ObjectsDictionary.Values);
            CurrentDocument.ObjectsDictionary.StartAccessList();

            //call operation
            if (OperationsDictionary.ContainsKey(operationName))
            {
                var operation = (UserOperation)Activator.CreateInstance(OperationsDictionary[operationName]);
                operation.OwnerDocument = CurrentDocument;
                ActiveOperations.Add(operation);

                OperationReturnValue        result = OperationReturnValue.CancelOperation;
                Task <OperationReturnValue> task   = new Task <OperationReturnValue>(operation.Execute);

                try
                {
                    task.Start();
                    result = await task;
                }
                catch (Exception e)
                {
                    Log.Error(e.Message);
                }

                if (result == OperationReturnValue.EndOperation)
                {
                    ActiveOperations.Remove(operation);
                    foreach (var o in new Dictionary <int, CADObject>(operation.TemporaryObjectsDictionary))
                    {
                        CurrentDocument.PostCreateCADObject(o.Value);
                        o.Value.LockOperation = null;
                    }
                    EndOperation(operation);
                }
                else
                {
                    ActiveOperations.Remove(operation);
                    operation.TemporaryObjectsDictionary.Clear();
                }
            }
        }
コード例 #4
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);
        }
コード例 #5
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++);
            ActiveOperations.Add(request.RequestID);

            request.MsgView = GetCurrentView();

            AsyncCallback remoteCallback = new AsyncCallback(AcksCallback);


            // Clear acks count
            AcksCounter = 0;
            // Repeat until all replicas have acknowledged receipt
            while (AcksCounter < Quorum())
            {
                // Send request to all replicas in the view
                this.Multicast(request, remoteCallback);
            }
            ActiveOperations.Remove(request.RequestID);

            Console.WriteLine("Add " + (++AddCounter) + ": OK");
        }
コード例 #6
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 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++);
                ActiveOperations.Add(request.RequestID);


                // 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 < Quorum())
                {
                    // 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;
                    }
                }
                ActiveOperations.Remove(request.RequestID);
            }
            Console.WriteLine("Read " + (++ReadCounter) + ": OK");

            // Return after the first replica answers
            return(Tuple);
        }
コード例 #7
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++);
                ActiveOperations.Add(request.RequestID);


                request.MsgView = GetCurrentView();



                //Clear acks from last request
                AcksCounter = 0;

                // Repeat untill all replicas have answered
                while (AcksCounter < Quorum())
                {
                    // 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;
                    }
                }
                ActiveOperations.Remove(request.RequestID);
            }

            Console.WriteLine("Take " + (++TakeCounter) + ": OK");
            return(Tuple);
        }
コード例 #8
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)
            {
                if (message.RequestID != null && ActiveOperations.Contains(message.RequestID))
                {
                    ActiveOperations.Remove(message.RequestID);
                }

                message.RequestID = ClientID + "_" + (++SequenceNumber);
                ActiveOperations.Add(message.RequestID);
                AcksCounter = 0;

                // Waits until one replica returns a tuple or
                // all replicas answered that they dont have a match
                while (AcksCounter < Quorum())
                {
                    // 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;
                    }
                }
            }
            ActiveOperations.Remove(message.RequestID);

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

            return(Tuple);
        }
コード例 #9
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();

            ActiveOperations.Add(message.RequestID);

            // 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 < Quorum())
            {
                //Send multicast take request to all members of the view
                this.Multicast(message, remoteCallback);
            }


            ActiveOperations.Remove(message.RequestID);

            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
                ActiveOperations.Add(message.RequestID);
                AcksCounter = 0;

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

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

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

            return(intersection[0]);
        }