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