Ejemplo n.º 1
0
        public ReservationMessage AbortReservation(ReservationMessage message, int timeout)
        {
            Console.WriteLine("[Calling] AbortReservation");
            Console.WriteLine("Cleaning Thread Lists");

            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("TwoPhaseCommit");
            }

            localThreadList.Clear();
            disseminationThreadList.Clear();
            threadResponses.Clear();
            threadResponses2.Clear();

            int reservationTicketNumber = message.reservation.getTicket();

            List<ReservationSlot> reservationSlotList = message.reservation.getSlotList();

            lock (User.ReservationPerSlot) {
                foreach (ReservationSlot rslot in reservationSlotList) {
                    //remove each reservation from the slots it was assigned to
                    ReservationPerSlot reservationOnTheSlot = User.ReservationPerSlot[rslot.GetNumber()];
                    foreach (Reservation r in reservationOnTheSlot.GetReservations()) {
                        if (r.getTicket().Equals(reservationTicketNumber)) {
                            User.ReservationPerSlot[rslot.GetNumber()].RemoveReservation(message.reservation);

                            if (!User.ReservationPerSlot[rslot.GetNumber()].HasReservations()) {
                                Console.WriteLine("Slot " + rslot.GetNumber() + " does not have any reservation. Set state to Free");
                                lock (User.Calendar) {
                                    User.Calendar[rslot.GetNumber()-1].setFree();
                                }
                            }
                        }
                    }
                }
            }

            return message;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Method the will be called by the threads the DisseminateReservationw will create.
        /// This method will make a remote call to a specific user (proxy)
        /// </summary>
        /// <param name="proxy"></param>
        /// <param name="reservation"></param>
        /// 
        private void CallSendReservation(object context)
        {
            Console.WriteLine("[Calling] CallSendReservation");
            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("CallSendReservation");
            }
            ThreadInfo threadInfo = context as ThreadInfo;
            UserInterface proxy = threadInfo.proxy;
            Reservation reservation = threadInfo.reservationMessage.reservation;
            Console.WriteLine("Thread Number: " + threadInfo.threadNumber);

            ReservationMessage response = null;
            RemoteAsyncDelegate remoteDelegate = new RemoteAsyncDelegate(proxy.SendReservation);

            String userName = threadInfo.userName;
            int originalMessageCounter = threadInfo.reservationMessage.messageCounter;

            String threadName = Thread.CurrentThread.Name;

            JacobsonKarels timeoutAlgoritm = User.KnownUsersTimeout[userName];
            timeoutAlgoritm.ModifiedUpdateTimeout();

            int timeout = timeoutAlgoritm.GetTimeout();

            //dissemination
            if (threadName.Length == 3)
            {
                timeout = timeout / 2;
            }

            IAsyncResult result = remoteDelegate.BeginInvoke(threadInfo.reservationMessage, timeout, null, null);
            //colocar timeout dinamico!
            bool responseInTime = result.AsyncWaitHandle.WaitOne(timeout, true);

            Console.WriteLine("Work time is over! Response in time? " + responseInTime);

            //didn't get a response till timeout
            if (responseInTime == false) {
                Console.WriteLine("Timeout! Did not receive any answer!");
                result.AsyncWaitHandle.Close();
                response = new ReservationMessage();
                //add an empty dicionary indicating that the user did not answered
                response.AddSlotResponse(userName, new Dictionary<int, String>());
                result.AsyncWaitHandle.Close();
            }
            else {
                IncrementUserTrust(threadInfo.userName);
                response = remoteDelegate.EndInvoke(result);
                Console.WriteLine("Received: " + response);
                result.AsyncWaitHandle.Close();
            }

            String currentThreadName = Thread.CurrentThread.Name;
            char[] separator = { ' ' };
            String[] splitedThreadName = currentThreadName.Split(separator);
            String currentThreadNumber = splitedThreadName[0];
            int currentTNumber = int.Parse(currentThreadNumber);

            if (threadResponses.ContainsKey(currentTNumber)) {
                threadResponses.Remove(currentTNumber);
            }

            //adds the response the response dicionary
            //if is the retry
            if (originalMessageCounter < 0) {
                if (threadResponses2.ContainsKey(threadInfo.userName))
                    threadResponses2.Remove(threadInfo.userName);
                threadResponses2.Add(threadInfo.userName, response);
            }
            else
                threadResponses.Add(threadInfo.threadNumber, response);
        }
Ejemplo n.º 3
0
        private void CallProposeSlot(object context)
        {
            Console.WriteLine("[Calling] CallProposeSlot");
            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("CallProposeSlot");
            }
            ThreadInfo threadInfo = context as ThreadInfo;
            UserInterface proxy = threadInfo.proxy;

            Console.WriteLine("Thread Number: " + threadInfo.threadNumber);

            ReservationMessage response = null;
            ProposeSlotAsyncDelegate remoteDelegate = new ProposeSlotAsyncDelegate(proxy.ProposeSlot);

            String userName = threadInfo.userName;

            JacobsonKarels timeoutAlgoritm = User.KnownUsersTimeout[userName];
            timeoutAlgoritm.ModifiedUpdateTimeout();

            int timeout = timeoutAlgoritm.GetTimeout();

            IAsyncResult result = remoteDelegate.BeginInvoke(threadInfo.reservationMessage.proposedSlot, threadInfo.reservationMessage, timeout, null, null);
            bool responseInTime = result.AsyncWaitHandle.WaitOne(timeout, true);

            Console.WriteLine("Work time is over! Response in time? " + responseInTime);

            //didn't get a response till timeout
            if (responseInTime == false) {
                Console.WriteLine("Timeout! Did not receive any answer!");
                result.AsyncWaitHandle.Close();
                response = new ReservationMessage();
                response.AddProposedSlotResponse(userName, "Timeout");
                result.AsyncWaitHandle.Close();
            }
            else {
                IncrementUserTrust(threadInfo.userName);
                response = remoteDelegate.EndInvoke(result);
                Console.WriteLine("User " + userName);
                Console.WriteLine("Proposed slot answer: " + response.GetProposedSlotResponseByUser(userName));
                result.AsyncWaitHandle.Close();

            }

            String currentThreadName = Thread.CurrentThread.Name;
            char[] separator = { ' ' };
            String[] splitedThreadName = currentThreadName.Split(separator);
            String currentThreadNumber = splitedThreadName[0];
            int currentTNumber = int.Parse(currentThreadNumber);

            if (threadResponses.ContainsKey(currentTNumber)) {
                threadResponses.Remove(currentTNumber);
            }
            threadResponses.Add(threadInfo.threadNumber, response);
            return;
        }
Ejemplo n.º 4
0
        public ReservationMessage TwoPhaseCommit(ReservationMessage message, int timeout)
        {
            Console.WriteLine("[Calling] TwoPhaseCommit");
             lock (User.userLoger)
             {
                 User.userLoger.IncrementNumberOfExchangedMessages("TwoPhaseCommit");
             }
             ReservationMessage response = new ReservationMessage();

                if (User.connected == false)
                {
                    Console.WriteLine("I am not connect. Do not answer call");
                    Thread.Sleep(2 * timeout);
                    return response;
                }

                response.response2PC.Add(User.Name, "YES");
                response.messageCounter += 1;
                response.senderName = User.Name;

                bool isDisseminating = IsDisseminating("2PC");

                if (isDisseminating) return response;

                int lenght = 2;
                if (Thread.CurrentThread.Name == null)
                {
                    Console.WriteLine("Thread Name is null. Original remote invocation thread");
                }
                else
                {
                    String tName = Thread.CurrentThread.Name;
                    Console.WriteLine("Thread Name: " + tName);
                    char[] separator = { ' ' };
                    String[] words = tName.Split(separator);
                    lenght = words.Length;
                }

                //Calls the gossip dissemination protocol to send the message to other nodes
                //Before sending the message we need to remove the user that sent the message
                int userListSize = message.reservation.getUserList().Count;
                double userListDouble = (double)userListSize;
                double messageCounterDouble = (double)message.messageCounter;
                if ((messageCounterDouble <= (userListDouble / 2)) && (userListSize != 1) && messageCounterDouble > 0)
                {

                    if (Thread.CurrentThread.Name == null || lenght == 2)
                    {
                        Console.WriteLine("Disseminate!");
                        message.reservation = DeleteSenderFromUserList(message);
                        message.messageCounter *= 2;
                        DisseminateInformation(message, MessageTypeToDisseminate.TWO_PHASE_COMMIT, true);

                        //add received answers to the answer we will send
                        foreach (KeyValuePair<int, ReservationMessage> responses in threadResponses)
                        {

                            foreach (KeyValuePair<String, String> index in responses.Value.response2PC)
                            {
                                if(!response.response2PC.ContainsKey(index.Key))
                                response.response2PC.Add(index.Key,index.Value);
                            }
                        }
                    }
                    else Console.WriteLine("Thread has no permission to disseminate!");
                }
             return response;
        }
Ejemplo n.º 5
0
        public ReservationMessage SendReservation(ReservationMessage reservationMessage, int timeout)
        {
            Console.WriteLine("[Calling] SendReservation");

            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("SendReservation");
            }
            if (User.Calendar == null) {
                Console.WriteLine("Calendar is null...initializing it");
                CreateCalendar();
            }

            Console.WriteLine("Timeout to send message: " + timeout);
            if (User.connected == false) {
                Console.WriteLine("I am not connected. Do not answer call");
                Thread.Sleep(2 * timeout);
                return new ReservationMessage();
            }

            List<ReservationSlot> slotList = reservationMessage.reservation.getSlotList();
            bool isDisseminating = IsDisseminating("SEND_RESERVATION");

                if (isDisseminating)
                {
                    Dictionary<int, String> sResponse = ChangeCalendarSlotStatus(slotList, false);

                    ReservationMessage a = new ReservationMessage();
                    a.reservation = reservationMessage.reservation;
                    a.messageCounter *= 2;
                    a.senderName = User.Name;
                    a.AddSlotResponse(User.Name, sResponse);
                    return a;
                }

            List<UserView> unknownUsers = GetUnkownUsersFromReservationUserList(reservationMessage.reservation.getUserList());

            Console.WriteLine("Printing unknown users...");
            foreach (UserView u in unknownUsers) {
                Console.WriteLine("User: "******"Print received slots");
            foreach (ReservationSlot s in slotList) {
                Console.WriteLine(s.ToString());

                if (!ExistsReservationInTheList(reservationMessage.reservation, s.GetNumber())) {
                    User.ReservationPerSlot[s.GetNumber()].addReservation(reservationMessage.reservation);
                    Console.WriteLine("Added Reservation: " + User.ReservationPerSlot[s.GetNumber()].GetReservations()[0].ToString());
                }
                else Console.WriteLine("Reservation was already in the slot list. Do not add it");
            }
            Dictionary<int, String> slotResponse = ChangeCalendarSlotStatus(slotList, false);

            ReservationMessage answer = new ReservationMessage();
            answer.reservation = reservationMessage.reservation;
            answer.messageCounter *= 2;
            answer.senderName = User.Name;
            answer.AddSlotResponse(User.Name, slotResponse);

            int lenght = 2;
            if (Thread.CurrentThread.Name == null) {
                Console.WriteLine("Thread Name is null. Original remote invocation thread");
            }
            else {
                String tName = Thread.CurrentThread.Name;
                Console.WriteLine("Thread Name: " + tName);
                char[] separator = { ' ' };
                String[] words = tName.Split(separator);
                lenght = words.Length;
            }

            //Calls the gossip dissemination protocol to send the message to other nodes
            //Before sending the message we need to remove the user that sent the message
            int userListSize = reservationMessage.reservation.getUserList().Count;
            double userListDouble = (double)userListSize;
            double messageCounterDouble = (double)reservationMessage.messageCounter;
            if ((messageCounterDouble <= (userListDouble / 2)) && (userListSize != 1) && messageCounterDouble > 0) {

                if (Thread.CurrentThread.Name == null || lenght == 2) {
                    Console.WriteLine("Disseminate!");
                    reservationMessage.reservation = DeleteSenderFromUserList(reservationMessage);
                    reservationMessage.messageCounter *= 2;
                    PrintReservation(reservationMessage.reservation);
                    DisseminateInformation(reservationMessage, MessageTypeToDisseminate.SEND_RESERVATION, true);

                    //add received answers to the answer we will send
                    foreach (KeyValuePair<int, ReservationMessage> responses in threadResponses) {
                        Console.WriteLine("Thread " + responses.Key + " responses");
                        Console.WriteLine(responses.Value.PrintSlotResponses());

                        foreach (KeyValuePair<String, Dictionary<int, String>> rpsIndex in responses.Value.GetAllResponses()) {
                            answer.AddSlotResponse(rpsIndex.Key, rpsIndex.Value);
                        }
                    }
                }
                else Console.WriteLine("Thread has no permission to disseminate!");
            }

            Console.WriteLine("Answer to send");
            Console.WriteLine(answer.ToString());
            return answer;
        }
Ejemplo n.º 6
0
        public ReservationMessage ProposeSlot(ReservationSlot slot, ReservationMessage reservation, int timeout)
        {
            Console.WriteLine("[Calling] ProposeSlot");
            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("ProposeSlot");
            }
            Console.WriteLine("Timeout to send message: " + timeout);
            if (User.connected == false) {
                Console.WriteLine("I am not connected. Do not answer call");
                Thread.Sleep(2 * timeout);
                return new ReservationMessage();
            }

            bool isDisseminating = IsDisseminating("PROPOSE"); ;

            List<Reservation> rsvList = User.ReservationPerSlot[slot.GetNumber()].GetReservations();
            Console.WriteLine("Proposed slot: " + slot.GetNumber());
            ReservationMessage response = new ReservationMessage();
            response.senderName = User.Name;

            if (rsvList.Count == 1) {
                Console.WriteLine("Slot Found! Send Ack");
                if (!response.GetAllProposedSlotResponses().ContainsKey(response.senderName))
                    response.AddProposedSlotResponse(User.Name, "Ack");
            }
            else {
                bool isNak = false;

                foreach (Reservation r in rsvList) {
                    if (r.areEqual(reservation.reservation))
                        continue;

                    //exists a reservation for this slot whose ticket number is lower
                    if (r.getTicket() < reservation.reservation.getTicket()) {
                        Console.WriteLine("A reservation with a lower ticket number was found! It has higher priority! Send Nak");
                        if (!response.GetAllProposedSlotResponses().ContainsKey(response.senderName)) {
                            response.AddProposedSlotResponse(response.senderName, "Nak");
                            isNak = true;
                        }
                        //return "Nak";
                    }
                }

                if (!isNak) {
                    if (!response.GetAllProposedSlotResponses().ContainsKey(response.senderName))
                        response.AddProposedSlotResponse(response.senderName, "Ack");
                }
            }

            if (isDisseminating)
                return response;

            int lenght = 2;
            if (Thread.CurrentThread.Name == null) {
                Console.WriteLine("Thread Name is null. Original remote invocation thread");
            }
            else {
                String tName = Thread.CurrentThread.Name;
                Console.WriteLine("Thread Name: " + tName);
                char[] separator = { ' ' };
                String[] words = tName.Split(separator);
                lenght = words.Length;
            }

            //Calls the gossip dissemination protocol to send the message to other nodes
            //Before sending the message we need to remove the user that sent the message
            int userListSize = reservation.reservation.getUserList().Count;
            double userListDouble = (double)userListSize;
            double messageCounterDouble = (double)reservation.messageCounter;
            if ((messageCounterDouble <= (userListDouble / 2)) && (userListSize != 1)) {
                if (Thread.CurrentThread.Name == null || lenght == 2) {

                    Console.WriteLine("Disseminate!");
                    reservation.reservation = DeleteSenderFromUserList(reservation);
                    reservation.messageCounter *= 2;
                    Console.WriteLine("Thread responses size: " + threadResponses.Count);
                    DisseminateInformation(reservation, MessageTypeToDisseminate.PROPOSE_SLOT, true);

                    //add received answers to the answer we will send
                    foreach (KeyValuePair<int, ReservationMessage> responses in threadResponses) {
                        Console.WriteLine("Thread " + responses.Key + " responses");
                        foreach (KeyValuePair<String, String> x in responses.Value.GetAllProposedSlotResponses()) {
                        }
                        Console.WriteLine(responses.Value.PrintSlotResponses());

                        //only adds the response if it does not exist
                        if (!response.GetAllProposedSlotResponses().ContainsKey(responses.Value.senderName))
                            response.AddProposedSlotResponse(responses.Value.senderName, responses.Value.GetProposedSlotResponseByUser(responses.Value.senderName));

                    }
                }
                else Console.WriteLine("Thread has no permission to disseminate!");
            }

            Console.WriteLine("Printing answer");
            foreach (KeyValuePair<String, String> i in response.GetAllProposedSlotResponses()) {
                Console.WriteLine("User " + i.Key + "  response: " + i.Value);
            }
            return response;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Changes the slots that are TB on the reservation to Booked on the Calendar
        /// </summary>
        /// <param name="reservation"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public ReservationMessage ReservationSlotsUpdate(ReservationMessage reservation, int timeout)
        {
            if (User.Calendar == null) CreateCalendar();

            Console.WriteLine("[Calling] Reservation Slots Update");
            if (User.connected == false) {
                Console.WriteLine("I am not connected. Do not answer call");
                Thread.Sleep(2 * timeout);
                return new ReservationMessage();
            }

            lock (User.Calendar) {
                foreach (ReservationSlot slot in reservation.reservation.getSlotList()) {
                    UserCalendarSlot calendarSlot = User.Calendar[slot.GetNumber()-1];
                    if (slot.isTentativelyBooked() && !calendarSlot.isBooked() && !calendarSlot.isAssigned()) {
                        Console.WriteLine("Setting slot " + slot.GetNumber() + " to Booked");
                        User.Calendar[slot.GetNumber()-1].setBooked();
                    }

                    else
                        Console.WriteLine("Slot is not TB. Do not set calendar slot to Booked");
                }
            }
            return reservation;
        }
Ejemplo n.º 8
0
        public void CreateReservation(String description, List<UserView> userList, List<ReservationSlot> slotList, String creator, MasterInterface master)
        {
            if (!User.IsRegistered) {
                User.Register();
            }

            Console.WriteLine("[Calling] CreateReservation");
            Console.WriteLine("Printing slot list..");

            foreach (ReservationSlot s in slotList) {
                Console.WriteLine(s.ToString());
            }

            int ticket = master.RequestTicketNumber();

            Reservation reservation = new Reservation(description, userList, slotList, creator, ticket);

            //reservation has no participants. Medical dentist consult example
            if (userList.Count == 0)
            {
                Console.WriteLine("No participants");
                SinglePersonReservation(slotList, reservation);
                return;
            }

            User.CreatedReservations.Add(reservation);
            ChangeCalendarSlotStatus(slotList, true);

            ReservationMessage reservationMessage = new ReservationMessage();
            reservationMessage.senderName = User.Name;
            reservationMessage.reservation = reservation;
            reservationMessage.messageCounter = 1;

            //send reservation
            DisseminateInformation(reservationMessage, MessageTypeToDisseminate.SEND_RESERVATION,false);

            List<UserView> usersThatNotAnswered = UsersThatNotAnsweredSendReservationCall(reservationMessage.reservation, false);

            if (usersThatNotAnswered.Count == 0) {
                Console.WriteLine("All users have answered");
            }
            else {
                List<UserView> newList = RemoveUsersThatNotAnsweredFromTheUserList(reservationMessage.reservation.getUserList(), usersThatNotAnswered);
                localThreadList.Clear();
                threadResponses.Clear();
                threadResponses2.Clear();
                disseminationThreadList.Clear();

                PrepareRetrySendReservation(usersThatNotAnswered, reservationMessage);

                usersThatNotAnswered.Clear();
                usersThatNotAnswered = UsersThatNotAnsweredSendReservationCall(reservationMessage.reservation, true);

                Console.WriteLine("Not answered retry!");
                foreach (UserView u in usersThatNotAnswered) {
                    Console.WriteLine("User " + u.getName() + " did not answered. Dead? Maybe...");
                }

                newList = RemoveUsersThatNotAnsweredFromTheUserList(reservationMessage.reservation.getUserList(), usersThatNotAnswered);
                if (newList.Count == 0) {
                    DisseminateInformation(reservationMessage, MessageTypeToDisseminate.ABORT_RESERVATION, false);
                    localThreadList.Clear(); disseminationThreadList.Clear();
                    threadResponses.Clear(); threadResponses2.Clear();
                    return;
                }
                reservationMessage.reservation.SetUserList(newList);
            }

            localThreadList.Clear();

            //changes the reservation slot status based on the answers received
            //if the reservation if null them all slots are aborted -> Abort the reservation

            Reservation temporaryReservation = null;

            temporaryReservation = ChangeReservationSlotStatus(reservationMessage.reservation);

            if (temporaryReservation == null) {
                DisseminateInformation(reservationMessage, MessageTypeToDisseminate.ABORT_RESERVATION, false);
                localThreadList.Clear();
                threadResponses.Clear();
                return;
            }

            reservationMessage.reservation = temporaryReservation;

            reservationMessage.reservation = DeleteAbortedSlotsFromReservation(reservationMessage.reservation);
            PrintReservation(reservationMessage.reservation);  //debug

            threadResponses.Clear();

            //sends information to the users about the state of the reservation slots
            DisseminateInformation(reservationMessage, MessageTypeToDisseminate.UPDATE_USERS_RESERVATION_INFO, false);

            //remove the aborted slots from the slotList and start proposing possible slots for the event
            localThreadList.Clear();
            threadResponses.Clear();

            //there are no avaible slots
            if (reservationMessage.reservation.getSlotList().Count == 0) {
                Console.WriteLine("No avaiable slots. Abort Reservation");
                DisseminateInformation(reservationMessage, MessageTypeToDisseminate.ABORT_RESERVATION, false);
                localThreadList.Clear();
                threadResponses.Clear();
                return;
            }

            bool wasAccepted = false;
            int slotListSize = reservationMessage.reservation.getSlotList().Count;
            ReservationMessage proposedSlotMessage = new ReservationMessage();
            ReservationSlot commitSlot = null;

            for (int i = 0; i <= slotListSize; i++) {
                proposedSlotMessage = CreateMessageWithProposedSlot(reservationMessage.reservation, reservationMessage.reservation.getSlotList()[i]);
                DisseminateInformation(proposedSlotMessage, MessageTypeToDisseminate.PROPOSE_SLOT, false);

                //check if the proposed slot was accepted by all participants
                wasAccepted = WasProposedSlotAccepted(proposedSlotMessage.proposedSlot);

                if (wasAccepted) {
                    {
                        commitSlot = proposedSlotMessage.proposedSlot;
                        break;
                    }
                }

                localThreadList.Clear();
                threadResponses.Clear();
            }

            Console.WriteLine("Was accepted? " + wasAccepted);
            if (!wasAccepted) {
                Console.WriteLine("No slot was accepted! Abort Reservation");
                DisseminateInformation(reservationMessage, MessageTypeToDisseminate.ABORT_RESERVATION, false);
                localThreadList.Clear();
                threadResponses.Clear();
                return;
            }

            Console.WriteLine("AcceptedSlot\n" + proposedSlotMessage.proposedSlot.ToString());
            localThreadList.Clear();
            threadResponses.Clear();

            Console.WriteLine("Starting 2PC");
            DisseminateInformation(reservationMessage, MessageTypeToDisseminate.TWO_PHASE_COMMIT, false);
            usersThatNotAnswered.Clear();
            usersThatNotAnswered = UsersThatNotAnsweredTwoPhaseCommit(reservationMessage.reservation,false);

            if (usersThatNotAnswered.Count == 0)
            {
                Console.WriteLine("All users have answered");
            }
            else
            {
                List<UserView> newList = RemoveUsersThatNotAnsweredFromTheUserList(reservationMessage.reservation.getUserList(), usersThatNotAnswered);

                PrepareRetryTwoPhaseCommit(usersThatNotAnswered, reservationMessage);

                usersThatNotAnswered.Clear();
                usersThatNotAnswered = UsersThatNotAnsweredTwoPhaseCommit(reservationMessage.reservation, true);

                foreach (UserView u in usersThatNotAnswered)
                {
                    Console.WriteLine("User " + u.getName() + " did not answered. Dead? Maybe...");
                }

                newList = RemoveUsersThatNotAnsweredFromTheUserList(reservationMessage.reservation.getUserList(), usersThatNotAnswered);
                if (newList.Count == 0)
                {
                    DisseminateInformation(reservationMessage, MessageTypeToDisseminate.ABORT_RESERVATION, false);
                    localThreadList.Clear(); disseminationThreadList.Clear();
                    threadResponses.Clear(); threadResponses2.Clear();
                    return;
                }
                reservationMessage.reservation.SetUserList(newList);
            }

            Console.WriteLine("Send Commit Reservation!");
            ReservationMessage commitMessage = new ReservationMessage();
            commitMessage.slotToCommit = commitSlot;
            commitMessage.reservation = reservationMessage.reservation;
            commitMessage.senderName = User.Name;
            commitMessage.messageCounter = 1;
            DisseminateInformation(commitMessage, MessageTypeToDisseminate.COMMIT_RESERVATION,false) ;
            CommitReservation(commitMessage, 2000);
            localThreadList.Clear();
            threadResponses.Clear();
        }
Ejemplo n.º 9
0
        private void PrepareRetryTwoPhaseCommit(List<UserView> listToSend, ReservationMessage reservation)
        {
            Console.WriteLine("[Calling] PrepareRetryTwoPhaseCommit");
            List<UserInterface> usersProxy = new List<UserInterface>();

            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("TwoPhaseCommit");
            }

            foreach (UserView u in listToSend)
            {
                UserInterface proxy = User.GetUser(u.getIPAddress(), u.getPort(), u.getName());
                usersProxy.Add(proxy);
            }

            Console.WriteLine("Creating Threads...");
            int i = 0;
            foreach (UserInterface ui in usersProxy)
            {
                ThreadInfo threadInfo = new ThreadInfo();
                threadInfo.proxy = ui;
                threadInfo.userName = ui.getName();
                threadInfo.sendUserName = User.Name;
                threadInfo.reservationMessage = reservation;
                threadInfo.threadNumber = i++;

                //send a message counter equal to the user list size to avoid further dissemination
                threadInfo.reservationMessage.messageCounter = -1;
                Thread t = new Thread(delegate()
                {
                    CallTwoPhaseCommit(threadInfo);
                });

                t.Name = threadInfo.threadNumber + " 2PC";
                localThreadList.Add(t);
                t.Start();
            }

            Console.WriteLine("Waiting for threads to finish...");
            foreach (Thread t in localThreadList)
            {
                t.Join();
            }
            Console.WriteLine("all threads have finished!");
        }
Ejemplo n.º 10
0
        private void DisseminateInformation(ReservationMessage reservationMessage, MessageTypeToDisseminate typeOfMessage, bool secondDissemination)
        {
            Console.WriteLine("[Calling] DisseminateReservation");
            Console.WriteLine("Mode-> " + typeOfMessage.ToString());
            Console.WriteLine("");

            List<UserView> chosenUsers = null;
            if (typeOfMessage.Equals(MessageTypeToDisseminate.UPDATE_USERS_RESERVATION_INFO) || typeOfMessage.Equals(MessageTypeToDisseminate.ABORT_RESERVATION) || typeOfMessage.Equals(MessageTypeToDisseminate.COMMIT_RESERVATION)) {
                chosenUsers = reservationMessage.reservation.getUserList();
            }
            else
                chosenUsers = ChooseUsers(reservationMessage.reservation,reservationMessage.messageCounter);

            Console.WriteLine("Printing chosen users..");
            foreach (UserView u in chosenUsers) {
                Console.WriteLine(u.getName() + " port: " + u.getPort());
            }

            List<UserInterface> chosenUsersProxys = new List<UserInterface>();

            foreach (UserView u in chosenUsers) {
                UserInterface proxy = User.GetUser(u.getIPAddress(), u.getPort(), u.getName());
                chosenUsersProxys.Add(proxy);
            }

            Console.WriteLine("Creating Threads...");
            int i = 0;
            foreach (UserInterface ui in chosenUsersProxys) {
                ThreadInfo threadInfo = new ThreadInfo();
                threadInfo.proxy = ui;
                threadInfo.userName = ui.getName();  //caso
                threadInfo.sendUserName = User.Name;
                threadInfo.reservationMessage = reservationMessage;
                threadInfo.threadNumber = i++;

                if (secondDissemination) threadInfo.secondDissemination = true;
                else threadInfo.secondDissemination = false;

                Thread t;
                if (typeOfMessage.Equals(MessageTypeToDisseminate.SEND_RESERVATION)) {

                    t = new Thread(delegate() {
                         CallSendReservation(threadInfo);
                     });
                    if (secondDissemination)
                        t.Name = threadInfo.threadNumber + " SEND_RESERVATION HAS_DISSEMINATED";
                    else
                        t.Name = threadInfo.threadNumber + " SEND_RESERVATION";
                }

                else if (typeOfMessage.Equals(MessageTypeToDisseminate.UPDATE_USERS_RESERVATION_INFO)) {
                    t = new Thread(delegate() {
                        CallUpdateUsersReservationInfo(threadInfo);
                    });

                    if (secondDissemination)
                        t.Name = threadInfo.threadNumber + " UPDATE HAS_DISSEMINATED";
                    else
                        t.Name = threadInfo.threadNumber + " UPDATE";
                }

                else if (typeOfMessage.Equals(MessageTypeToDisseminate.ABORT_RESERVATION)) {
                    t = new Thread(delegate() {
                            CallAbortReservation(threadInfo);
                        });
                    t.Name = threadInfo.threadNumber + " ABORT";
                }

                else if (typeOfMessage.Equals(MessageTypeToDisseminate.COMMIT_RESERVATION))
                {
                    t = new Thread(delegate()
                        {
                            CallCommitReservation(threadInfo);
                        });
                    if (secondDissemination)
                        t.Name = threadInfo.threadNumber + " COMMIT HAS_DISSEMINATED";
                    else
                        t.Name = threadInfo.threadNumber + " COMMIT";
                }

                else if (typeOfMessage.Equals(MessageTypeToDisseminate.TWO_PHASE_COMMIT))
                {
                    t = new Thread(delegate()
                        {
                            CallTwoPhaseCommit(threadInfo);
                        });
                    if (secondDissemination)
                        t.Name = threadInfo.threadNumber + " 2PC HAS_DISSEMINATED";
                    else
                        t.Name = threadInfo.threadNumber + " 2PC";
                }
                else
                {
                    t = new Thread(delegate()
                    {
                        CallProposeSlot(threadInfo);
                    });

                    if (secondDissemination)
                        t.Name = threadInfo.threadNumber + " PROPOSE HAS_DISSEMINATED";
                    else
                        t.Name = threadInfo.threadNumber + " PROPOSE";
                }

                //needs to check if there is a thread with the same number on the list
                //if there is...remove it and add the new one (t)

                String currentThreadName = t.Name;
                char[] separator = { ' ' };
                String[] splitedThreadName = currentThreadName.Split(separator);
                String currentThreadNumber = splitedThreadName[0];
                int currentTNumber = int.Parse(currentThreadNumber);

                Thread td = ThreadExistsInThreadList(currentTNumber);

                //exists...
                if (td != null) {
                    localThreadList.Remove(td);
                }

                if (secondDissemination.Equals(true)) {

                    disseminationThreadList.Add(t);
                }
                else
                    localThreadList.Add(t);

                Console.WriteLine("Created thread " + t.Name);
                t.Start();
            }

            Console.WriteLine("Waiting for threads to finish...");
            if (secondDissemination.Equals(true)) {

                foreach (Thread t in disseminationThreadList) {
                    t.Join();
                }
            }
            else {
                foreach (Thread t in localThreadList) {
                    t.Join();
                }
            }

            Console.WriteLine("all threads have finished!");
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Deletes the sender from the reservation user's list. This must be done to proceed with the dissemination
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        private Reservation DeleteSenderFromUserList(ReservationMessage message)
        {
            Reservation reservation = message.reservation;
            UserView sender = null;

            foreach (UserView user in User.KnownUsers.Keys.ToList()) {
                if (user.getName().Equals(message.senderName)) {
                    sender = user;
                    break;
                }
            }

            reservation.getUserList().Remove(sender);
            return reservation;
        }
Ejemplo n.º 12
0
        public ReservationMessage CommitReservation(ReservationMessage message, int timeout)
        {
            Console.WriteLine("[Calling] CommitReservation");
            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("CommitReservation");
            }
            ReservationMessage response=null;
            ReservationSlot slotToCommit = message.slotToCommit;

            lock (User.Calendar)
            {
                User.Calendar[slotToCommit.GetNumber() - 1].SetAssigned();
            }
            return response;
        }
Ejemplo n.º 13
0
 private ReservationMessage CreateMessageWithProposedSlot(Reservation reservation, ReservationSlot proposedSlot)
 {
     Console.WriteLine("[Calling] CreateMessageWithProposedSlot\nSlot: " + proposedSlot.GetNumber());
     ReservationMessage messageWithProposedSlot = new ReservationMessage();
     messageWithProposedSlot.reservation = reservation;
     messageWithProposedSlot.proposedSlot = proposedSlot;
     return messageWithProposedSlot;
 }
Ejemplo n.º 14
0
        private void CallTwoPhaseCommit(object context)
        {
            ThreadInfo threadInfo = context as ThreadInfo;
            UserInterface proxy = threadInfo.proxy;
            Console.WriteLine("Thread Number: " + threadInfo.threadNumber);
            lock (User.userLoger)
            {
                User.userLoger.IncrementNumberOfExchangedMessages("CallTwoPhaseCommit");
            }
            ReservationMessage response = new ReservationMessage();
            RemoteAsyncDelegate remoteDelegate = new RemoteAsyncDelegate(proxy.TwoPhaseCommit);

            String userName = threadInfo.userName;

            JacobsonKarels timeoutAlgoritm = User.KnownUsersTimeout[userName];
            timeoutAlgoritm.ModifiedUpdateTimeout();

            int timeout = timeoutAlgoritm.GetTimeout();

            IAsyncResult result = remoteDelegate.BeginInvoke(threadInfo.reservationMessage, timeout, null, null);
            bool responseInTime = result.AsyncWaitHandle.WaitOne(timeout, true);

            Console.WriteLine("Work time is over! Response in time? " + responseInTime);

            //didn't get a response till timeout
            if (responseInTime == false)
            {
                Console.WriteLine("Timeout! Did not receive any answer!");
                if(!response.response2PC.ContainsKey(userName))
                    response.response2PC.Add(userName,"Timeout");;
                result.AsyncWaitHandle.Close();
                return;
            }

            if (!response.response2PC.ContainsKey(userName))
                 response.response2PC.Add(userName, "YES");
            IncrementUserTrust(threadInfo.userName);
            response = remoteDelegate.EndInvoke(result);
            Console.WriteLine("Can Commit!");
            result.AsyncWaitHandle.Close();

            String currentThreadName = Thread.CurrentThread.Name;
            char[] separator = { ' ' };
            String[] splitedThreadName = currentThreadName.Split(separator);
            String currentThreadNumber = splitedThreadName[0];
            int currentTNumber = int.Parse(currentThreadNumber);

            if (threadResponses.ContainsKey(currentTNumber))
            {
                threadResponses.Remove(currentTNumber);
            }

            int originalMessageCounter = threadInfo.reservationMessage.messageCounter;
            //if is the retry
            if (originalMessageCounter < 0)
            {
                if (threadResponses2.ContainsKey(threadInfo.userName))
                    threadResponses2.Remove(threadInfo.userName);
                threadResponses2.Add(threadInfo.userName, response);
            }
            else
                threadResponses.Add(threadInfo.threadNumber, response);
        }