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