Exemple #1
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);
        }
Exemple #2
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;
        }