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