예제 #1
0
파일: User.cs 프로젝트: JoaoVasques/PadiCal
 public void addReservation(Reservation r)
 {
     this.reservationsOfThisSlot.Add(r);
 }
예제 #2
0
파일: User.cs 프로젝트: JoaoVasques/PadiCal
 public void RemoveReservation(Reservation r)
 {
     Console.WriteLine("[ReservationPerSlot] - Removing reservation with ticket number: " + r.getTicket());
     this.reservationsOfThisSlot.Remove(r);
 }
예제 #3
0
        private List<UserView> UsersThatNotAnsweredSendReservationCall(Reservation originalReservation, bool retrySend)
        {
            Console.WriteLine("[Calling] UsersThatNotAnsweredSendReservationCall");

            List<UserView> listOfUsers = new List<UserView>();
            List<UserView> orignalList = originalReservation.getUserList();
            List<UserView> auxList = new List<UserView>();

            if (retrySend == false) {
                Console.WriteLine("No retry");
                foreach (KeyValuePair<int, ReservationMessage> answers in threadResponses) {
                    foreach (KeyValuePair<String, Dictionary<int, String>> index in answers.Value.GetAllResponses()) {
                        UserView u = GetKnownUserByName(index.Key);
                        //if the dicionary is empty then the user has not answered
                        if (index.Value.Count == 0) {
                            Console.WriteLine("User " + u.getName() + " has not answered");
                            listOfUsers.Add(u);
                        }
                        else
                            auxList.Add(u); //if the user has answered add it to the aux list
                    }
                }

            }

            else {
                Console.WriteLine("Retry.");
                foreach (KeyValuePair<String, ReservationMessage> answers in threadResponses2) {
                    foreach (KeyValuePair<String, Dictionary<int, String>> index in answers.Value.GetAllResponses()) {
                        UserView u = GetKnownUserByName(index.Key);
                        //if the dicionary is empty then the user has not answered
                        if (index.Value.Count == 0)
                        {
                            Console.WriteLine("User " + u.getName() + " has not answered");
                            listOfUsers.Add(u);
                        }
                        else
                        {
                            Console.WriteLine(u.getName() + " has answered");
                            auxList.Add(u); //if the user has answered add it to the aux list
                        }
                    }
                }
            }

            foreach (UserView u in orignalList) {
                if (!IsUserInTheList(u, auxList) && !IsUserInTheList(u, listOfUsers))
                    listOfUsers.Add(u);
            }

            Console.WriteLine("users that have not answered...");
            foreach (UserView uka in listOfUsers) {
                Console.WriteLine(uka.getName());
            }

            return listOfUsers;
        }
예제 #4
0
        private List<UserView> UsersThatNotAnsweredTwoPhaseCommit(Reservation reservationn, bool retry)
        {
            List<UserView> listOfUsers = new List<UserView>();
            List<UserView> orignalList = reservationn.getUserList();
            List<UserView> auxList = new List<UserView>();

            if (retry == false)
            {
                Console.WriteLine("No retry");
                foreach (KeyValuePair<int, ReservationMessage> answers in threadResponses)
                {
                    foreach (KeyValuePair<String, String> index in answers.Value.response2PC)
                    {
                        UserView u = GetKnownUserByName(index.Key);
                        //if the dicionary is empty then the user has not answered
                        if (index.Value.Equals("Timeout"))
                        {
                            Console.WriteLine("User " + u.getName() + " has not answered");
                            listOfUsers.Add(u);
                        }
                        else
                            auxList.Add(u); //if the user has answered add it to the aux list
                    }
                }

            }

            else
            {
                Console.WriteLine("Retry.");
                foreach (KeyValuePair<String, ReservationMessage> answers in threadResponses2)
                {
                    foreach (KeyValuePair<String,String> index in answers.Value.response2PC)
                    {
                        UserView u = GetKnownUserByName(index.Key);
                        //if the dicionary is empty then the user has not answered
                        if (index.Value.Equals("Timeout"))
                        {
                            Console.WriteLine("User " + u.getName() + " has not answered");
                            listOfUsers.Add(u);
                        }
                        else
                            auxList.Add(u); //if the user has answered add it to the aux list
                    }
                }
            }

            foreach (UserView u in orignalList)
            {
                if (!IsUserInTheList(u, auxList) && !IsUserInTheList(u, listOfUsers))
                    listOfUsers.Add(u);
            }

            Console.WriteLine("users that have not answered...");
            foreach (UserView uka in listOfUsers)
            {
                Console.WriteLine(uka.getName());
            }

            return listOfUsers;
        }
예제 #5
0
        /// <summary>
        /// Debug Method
        /// Prints reservation information
        /// </summary>
        /// <param name="reservation"></param>
        private void PrintReservation(Reservation reservation)
        {
            Console.WriteLine("[Calling] PrintReservation");
            Console.WriteLine("RESERVATION");
            if (reservation.getCreator() == null) {
                Console.WriteLine("[Error]: Creator is Null");
                return;
            }

            if (reservation.getDescription() == null) {
                Console.WriteLine("[Error]: Description is null");
                return;
            }
            Console.WriteLine("Description: " + reservation.getDescription());

            if (reservation.getUserList().Count == 0) {
                Console.WriteLine("[Error]: User list is empty");
                return;
            }
            Console.WriteLine("User List");
            foreach (UserView u in reservation.getUserList()) {
                Console.WriteLine(u.getName());
            }

            if (reservation.getSlotList().Count == 0) {
                Console.WriteLine("[Error]: Slot list is empty");
                return;
            }
            foreach (ReservationSlot s in reservation.getSlotList()) {
                Console.WriteLine(s.ToString());
            }
        }
예제 #6
0
        /// <summary>
        /// Called when the reservation is a single person one. E.g. medical consult
        /// </summary>
        /// <param name="slotList"></param>
        private void SinglePersonReservation(List<ReservationSlot> slotList, Reservation reservation)
        {
            Console.WriteLine("[Calling] SinglePersonReservation");

            bool assigned = false;

            if (User.Calendar == null) CreateCalendar();

            lock (User.Calendar)
            {
                foreach (ReservationSlot slot in slotList)
                {
                    if (!User.Calendar[slot.GetNumber()-1].isBooked() && !User.Calendar[slot.GetNumber()-1].isAssigned())
                    {
                        User.Calendar[slot.GetNumber()-1].SetAssigned();
                        assigned = true;
                        User.ReservationPerSlot[slot.GetNumber()].addReservation(reservation);
                        break;
                    }
                }
            }
            if (assigned == false) Console.WriteLine("No suitable slot was found: ABORTED");
        }
예제 #7
0
        private bool ExistsReservationInTheList(Reservation reservation, int slotNumber)
        {
            Console.WriteLine("[Calling] ExistsReservationInTheList");
            Console.WriteLine("Reservation ticket number: " + reservation.getTicket());
            bool result = false;
            ReservationPerSlot reservationsPerTheSlotSelected;

            lock (User.ReservationPerSlot) {
                reservationsPerTheSlotSelected = User.ReservationPerSlot[slotNumber];
            }

            foreach (Reservation r in reservationsPerTheSlotSelected.GetReservations()) {
                if (r.getTicket().Equals(reservation.getTicket())) {
                    Console.WriteLine("Exists. Do not add");
                    result = true; break;
                }
            }

            return result;
        }
예제 #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();
        }
예제 #9
0
        private Reservation DeleteAbortedSlotsFromReservation(Reservation reservation)
        {
            Console.WriteLine("[Calling] DeleteAbortedSlotsFromReservation");
            List<ReservationSlot> newSlotList = new List<ReservationSlot>();

            foreach (ReservationSlot slot in reservation.getSlotList()) {
                if (slot.isAborted() == false) {
                    newSlotList.Add(slot);
                }
                else
                    Console.WriteLine("Slot " + slot.GetNumber() + " is aborted! Remove it");
            }

            Reservation reservationWithoutAbortedSlots = new Reservation(reservation.getDescription(), reservation.getUserList(), newSlotList, reservation.getCreator(), reservation.getTicket());
            return reservationWithoutAbortedSlots;
        }
예제 #10
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;
 }
예제 #11
0
        private List<UserView> ChooseUsers(Reservation reservation, int messageCounter)
        {
            Console.WriteLine("[Calling] ChooseUsers");

            int userListSize = reservation.getUserList().Count;
            float numberOfUsersToSelect = (float)System.Math.Round((float)userListSize /(2*(messageCounter)));

            if (userListSize == 1 || userListSize == 0) numberOfUsersToSelect = 1;

            Console.WriteLine("Number of User's to Select: " + numberOfUsersToSelect);
            List<UserView> selectedUsers = new List<UserView>();

            Dictionary<UserView, int> potencialUsers = new Dictionary<UserView, int>(); //contains the list of candidate users
            lock (User.KnownUsers)
            {
                foreach (KeyValuePair<UserView, int> u in User.KnownUsers)
                {

                    Console.WriteLine("Current User: "******" Trust: " + u.Value);
                    //if the user is in the reservation list and I know it, then he is a potential candidates
                    foreach (UserView r in reservation.getUserList())
                    {
                        if (r.getName().Equals(u.Key.getName()) && !r.getName().Equals(User.Name))
                        {
                            potencialUsers.Add(u.Key, u.Value);
                        }
                    }
                }
            }

            for (int i = 1; i <= numberOfUsersToSelect; i++) {
                int totalSum = CalculateTrustSum(potencialUsers);

                Dictionary<UserView, float> updatedPotentialUsers = new Dictionary<UserView, float>();

                foreach (KeyValuePair<UserView, int> u in potencialUsers) {
                    float trustRatio = CalculateTrustRatio(totalSum, u);
                    KeyValuePair<UserView, float> updatedUserwithTrustRatio = new KeyValuePair<UserView, float>(u.Key, trustRatio);
                    updatedPotentialUsers.Add(updatedUserwithTrustRatio.Key, updatedUserwithTrustRatio.Value);
                    //debug
                    Console.WriteLine("User " + updatedUserwithTrustRatio.Key.getName() + " Trust Ratio " + updatedPotentialUsers[updatedUserwithTrustRatio.Key]);
                }

                Dictionary<UserView, Tuple<float, float>> cumulativeDistributionFunction = new Dictionary<UserView, Tuple<float, float>>();

                //debug!
                Console.WriteLine("Printing potential users..");
                foreach (KeyValuePair<UserView, float> p in updatedPotentialUsers) {
                    Console.WriteLine("User: "******" Trust Ratio: " + p.Value);
                }

                cumulativeDistributionFunction = BuildCumulativeDistributionFunction(updatedPotentialUsers);
                PrintUsersInterval(cumulativeDistributionFunction);

                //generate a random number and sees which user cumulative function interval that number is in
                //that user will be the chosen one!

                System.Random randomNumberGenerator = new System.Random();
                float randomNumber = (float)randomNumberGenerator.NextDouble();

                Console.WriteLine("Random Number: " + randomNumber);

                foreach (KeyValuePair<UserView, Tuple<float, float>> u in cumulativeDistributionFunction) {
                    if (Between(randomNumber, u.Value.Item1, u.Value.Item2)) {
                        selectedUsers.Add(u.Key);
                        potencialUsers.Remove(u.Key);
                        break;
                    }
                }
            }//closes first for

            return selectedUsers;
        }
예제 #12
0
        /// <summary>
        /// Checks all the answers for each slot. If the answers were all Ack's them that slot changes
        /// its state to Tentatively-Booked. Otherwise, it changes its state to Aborted
        /// </summary>
        /// <param name="reservation"></param>
        /// <returns></returns>
        private Reservation ChangeReservationSlotStatus(Reservation reservation)
        {
            List<int> slotsWithNaks = AnyNAKReceived(threadResponses);

            Console.WriteLine("Print slot with naks");
            foreach (int i in slotsWithNaks) {
                Console.WriteLine("Slot " + i);
            }

            foreach (ReservationSlot slot in reservation.getSlotList()) {
                if (slotsWithNaks.Contains(slot.GetNumber())) {
                    slot.SetAborted();
                }
                else
                    slot.setTentativelyBooked();
            }

            bool areAllTheSlotsAborted = true;

            foreach (ReservationSlot s in reservation.getSlotList()) {
                if (!s.isAborted()) {
                    Console.WriteLine("Slot " + s.GetNumber() + " is not aborted!");
                    areAllTheSlotsAborted = false; break;
                }
            }

            if (areAllTheSlotsAborted) return null;
            return reservation;
        }
예제 #13
0
 public bool areEqual(Reservation r)
 {
     return this.description.Equals(r.description) && this.creator.Equals(r.creator) && this.ticketValue.Equals(r.ticketValue);
 }