예제 #1
0
        private Reservation UpdateReservation(List <ReservationSlot> participantReply, string userID)
        {
            Reservation reservation;

            if (participantReply.Count > 0)
            {
                ReservationSlot slot = participantReply[0];
                if (!_activeReservations.TryGetValue(slot.ReservationID, out reservation))
                {
                    Log.Show(_userName, "WARN: Could not find reservation " + slot.ReservationID);
                    return(null);
                }
            }
            else
            {
                return(null);
            }

            foreach (ReservationSlot rSlot in participantReply)
            {
                if (rSlot.State == ReservationSlotState.ABORTED)
                {
                    AbortReservationSlot(GetSlot(reservation, rSlot.SlotID), false);
                } //if
            }     //foreach

            reservation.Replied.Add(userID);

            return(reservation);
        }
예제 #2
0
        private void PrepareCommitOrBookNextSlot(Reservation res, int slotID)
        {
            Monitor.Enter(_calendar[slotID]);

            CalendarSlot    calendarSlot = _calendar[slotID];
            ReservationSlot slot         = GetSlot(res, slotID);

            if (calendarSlot.Locked || calendarSlot.State == CalendarSlotState.ASSIGNED || (calendarSlot.State == CalendarSlotState.BOOKED && res.ReservationID > calendarSlot.ReservationID))
            {
                Log.Show(_userName, "Booking of slot " + slotID + " of reservation " + res.ReservationID + " failed. Trying to book next slot.");

                AbortReservationSlot(slot, true);

                Monitor.Exit(_calendar[slotID]);

                BookNextSlot(res);
            }
            else
            {
                Log.Show(_userName, "Slot " + slotID + " of reservation " + res.ReservationID + " was booked successfully. Starting commit process.");

                LockCalendarSlot(res, slot);

                Monitor.Exit(_calendar[slotID]);

                foreach (string participantID in res.Participants)
                {
                    if (!participantID.Equals(_userName))
                    {
                        _msgDispatcher.SendMessage(MessageType.PRE_COMMIT, res.ReservationID, participantID, slot.SlotID);
                    }
                }
            }
        }
예제 #3
0
        void IBookingService.DoCommit(int resID, int slotID)
        {
            Log.Show(_userName, "Received Do Commit from initiator for slot " + slotID + " of  reservation " + resID + ". Assigning calendar.");

            //Fetch reservation and slot objects

            Reservation res;

            if (!_activeReservations.TryGetValue(resID, out res))
            {
                Log.Show(_userName, "WARN: Received doCommit from unknown reservation " + resID);
                return;
            }

            ReservationSlot resSlot = GetSlot(res, slotID);

            if (resSlot == null)
            {
                Log.Show(_userName, "WARN: Received do commit request from unknown reservation " + resID);
                return;
            }

            //GET LOCK HERE

            Monitor.Enter(_calendar[slotID]);

            AssignCalendarSlot(res, resSlot, true);

            Monitor.Exit(_calendar[slotID]);

            //RELEASE LOCK HERE

            res.InitiatorStub.DoCommitReply(resSlot.ReservationID, resSlot.SlotID, _userName, true);
        }
예제 #4
0
        private void AbortReservationSlot(ReservationSlot slot, bool locked)
        {
            Log.Debug(_userName, "Aborting slot " + slot.SlotID + " from reservation " + slot.ReservationID);

            if (slot != null)
            {
                slot.State = ReservationSlotState.ABORTED;
            }

            //IF NOT LOCKED GET LOCK HERE

            if (!locked)
            {
                Monitor.Enter(_calendar[slot.SlotID]);
            }

            FreeCalendarSlot(slot);

            if (!locked)
            {
                Monitor.Exit(_calendar[slot.SlotID]);
            }

            //IF NOT LOCKED RELEASE LOCK HERE
        }
예제 #5
0
        /*
         * CALENDAR SHOULD BE LOCKED BEFORE CALLING THIS METHOD
         */
        private void LockCalendarSlot(Reservation res, ReservationSlot resSlot)
        {
            //Change calendar and reservation slot states
            CalendarSlot calendarSlot = _calendar[resSlot.SlotID];

            calendarSlot.Locked = true;
            resSlot.State       = ReservationSlotState.COMMITTED;
        }
예제 #6
0
        /*
         * CALENDAR SHOULD BE LOCKED BEFORE CALLING THIS METHOD
         */
        private void BookCalendarSlot(Reservation res, ReservationSlot resSlot)
        {
            CalendarSlot calendarSlot = _calendar[resSlot.SlotID];

            calendarSlot.WaitingBook.Remove(resSlot.ReservationID);
            res.CurrentSlot            = resSlot.SlotID;
            calendarSlot.State         = CalendarSlotState.BOOKED;
            calendarSlot.ReservationID = resSlot.ReservationID;
            resSlot.State = ReservationSlotState.TENTATIVELY_BOOKED;
        }
예제 #7
0
        void IBookingService.BookSlot(int resID, int slotID)
        {
            Log.Show(_userName, "Received book request from initiator for slot " + slotID + " of  reservation " + resID);

            Reservation res;

            if (!_activeReservations.TryGetValue(resID, out res))
            {
                Log.Show(_userName, "WARN: Received book request from unknown reservation " + resID);
                return;
            }

            ReservationSlot resSlot = GetSlotAndAbortPredecessors(res, slotID);

            if (resSlot == null)
            {
                Log.Show(_userName, "WARN: Received book request from unknown reservation " + resID);
                return;
            }

            bool ack;

            Monitor.Enter(_calendar[slotID]);
            try
            {
                CalendarSlot calendarSlot = _calendar[slotID];
                calendarSlot.WaitingBook.Remove(resID);

                ack = !calendarSlot.Locked && (calendarSlot.State == CalendarSlotState.ACKNOWLEDGED || (calendarSlot.State == CalendarSlotState.BOOKED && resID < calendarSlot.ReservationID));

                if (ack)
                {
                    BookCalendarSlot(res, resSlot);
                }
                else
                {
                    AbortReservationSlot(resSlot, true);
                }
            }
            finally
            {
                Monitor.Exit(_calendar[slotID]);
            }

            res.InitiatorStub.BookReply(resSlot.ReservationID, resSlot.SlotID, _userName, ack);
        }
예제 #8
0
        void IBookingService.PrepareCommit(int resID, int slotID)
        {
            Log.Show(_userName, "Received prepare commit request from initiator for slot " + slotID + " of  reservation " + resID);

            //Fetch reservation and slot objects

            Reservation res;

            if (!_activeReservations.TryGetValue(resID, out res))
            {
                Log.Show(_userName, "WARN: Received pre-commit request from unknown reservation " + resID);
                return;
            }

            ReservationSlot resSlot = GetSlot(res, slotID);

            if (resSlot == null)
            {
                Log.Show(_userName, "WARN: Received prepare commit request from unknown reservation " + resID);
                return;
            }

            //GET LOCK HERE

            Monitor.Enter(_calendar[slotID]);

            CalendarSlot calendarSlot = _calendar[slotID];

            bool ack = !calendarSlot.Locked && calendarSlot.State == CalendarSlotState.BOOKED && calendarSlot.ReservationID == resID;

            if (ack)
            {
                LockCalendarSlot(res, resSlot);
            }
            else
            {
                AbortReservationSlot(resSlot, true);
            }

            Monitor.Exit(_calendar[slotID]);

            //RELEASE LOCK HERE

            res.InitiatorStub.PrepareCommitReply(resSlot.ReservationID, resSlot.SlotID, _userName, ack);
        }
예제 #9
0
        private void CommitSlot(Reservation res, int slotID)
        {
            ReservationSlot slot = GetSlot(res, slotID);

            Log.Show(_userName, "Slot " + slotID + " of reservation " + res.ReservationID + " was pre-committed successfully. Assigning calendar slot.");

            Monitor.Enter(_calendar[slotID]);

            AssignCalendarSlot(res, slot, false);

            Monitor.Exit(_calendar[slotID]);

            foreach (string participantID in res.Participants)
            {
                if (!participantID.Equals(_userName))
                {
                    _msgDispatcher.SendMessage(MessageType.DO_COMMIT, res.ReservationID, participantID, slot.SlotID);
                }
            }
        }
예제 #10
0
        //Verify calendar slots and create reservation states
        private List <ReservationSlot> CreateReservationSlots(ReservationRequest req, int resID)
        {
            List <ReservationSlot> reservationSlots = new List <ReservationSlot>();

            foreach (int slot in req.Slots)
            {
                ReservationSlotState state = ReservationSlotState.INITIATED;

                CalendarSlot calendarSlot;
                if (_calendar.TryGetValue(slot, out calendarSlot))
                {
                    if (calendarSlot.State == CalendarSlotState.ASSIGNED)
                    {
                        state = ReservationSlotState.ABORTED;
                    }
                }
                else
                {
                    calendarSlot         = new CalendarSlot();
                    calendarSlot.SlotNum = slot;
                    calendarSlot.State   = CalendarSlotState.FREE;

                    _calendar[slot] = calendarSlot;
                    Log.Debug(_userName, "Creating new calendar entry. Slot: " + calendarSlot.SlotNum + ". State: " + calendarSlot.State);
                }

                Monitor.Enter(calendarSlot);
                if (calendarSlot.State == CalendarSlotState.FREE)
                {
                    calendarSlot.State = CalendarSlotState.ACKNOWLEDGED;
                }
                Monitor.Exit(calendarSlot);
                calendarSlot.WaitingBook.Add(resID);

                ReservationSlot rs = new ReservationSlot(resID, slot, state);
                reservationSlots.Add(rs);
            }

            return(reservationSlots);
        }
예제 #11
0
        private bool CollectReply(int resID, int slotID, string userID, bool ack, out Reservation res)
        {
            if (!_activeReservations.TryGetValue(resID, out res))
            {
                Log.Show(_userName, "WARN: Received reply from unknown reservation " + resID);
                return(false);
            }

            if (res.CurrentSlot == slotID)
            {
                ReservationSlot slot = GetSlot(res, slotID);
                Monitor.Enter(slot);
                if (ack)
                {
                    Monitor.Exit(slot);
                    res.Replied.Add(userID);
                    if (res.Replied.Count == (res.Participants.Count - 1))
                    {
                        res.Replied.Clear();
                        return(true);
                    }
                }
                else if (slot.State != ReservationSlotState.ABORTED)
                {
                    AbortReservationSlot(slot, false);
                    Monitor.Exit(slot);
                    _msgDispatcher.ClearMessages(res.Participants, resID);
                    res.Replied.Clear();
                    BookNextSlot(res);
                }
                else
                {
                    Monitor.Exit(slot);
                }
                return(false);
            }

            return(false);
        }
예제 #12
0
        /*
         * CALENDAR SHOULD BE LOCKED BEFORE CALLING THIS METHOD
         */
        private void AssignCalendarSlot(Reservation res, ReservationSlot resSlot, bool clean)
        {
            //Change calendar and reservation slot states
            CalendarSlot calendarSlot = _calendar[resSlot.SlotID];

            calendarSlot.State         = CalendarSlotState.ASSIGNED;
            calendarSlot.ReservationID = res.ReservationID;
            calendarSlot.Participants  = res.Participants;
            calendarSlot.Description   = res.Description;

            foreach (ReservationSlot slot in res.Slots)
            {
                if (slot != resSlot && slot.State != ReservationSlotState.ABORTED)
                {
                    AbortReservationSlot(slot, true);
                }
            }

            if (clean)
            {
                CleanReservation(res);
            }
        }
예제 #13
0
        private void FreeCalendarSlot(ReservationSlot slot)
        {
            CalendarSlot cSlot = _calendar[slot.SlotID];

            cSlot.WaitingBook.Remove(slot.ReservationID);

            if (cSlot.State == CalendarSlotState.ACKNOWLEDGED && cSlot.WaitingBook.Count == 0)
            {
                cSlot.State = CalendarSlotState.FREE;
            }
            else if (cSlot.State == CalendarSlotState.BOOKED && cSlot.ReservationID == slot.ReservationID)
            {
                if (cSlot.WaitingBook.Count > 0)
                {
                    cSlot.State = CalendarSlotState.ACKNOWLEDGED;
                }
                else
                {
                    cSlot.State = CalendarSlotState.FREE;
                }
                cSlot.Locked = false;
            }
        }
예제 #14
0
 /*
  * CALENDAR SHOULD BE LOCKED BEFORE CALLING THIS METHOD
  */
 private void LockCalendarSlot(Reservation res, ReservationSlot resSlot)
 {
     //Change calendar and reservation slot states
     CalendarSlot calendarSlot = _calendar[resSlot.SlotID];
     calendarSlot.Locked = true;
     resSlot.State = ReservationSlotState.COMMITTED;
 }
예제 #15
0
        private void FreeCalendarSlot(ReservationSlot slot)
        {
            CalendarSlot cSlot = _calendar[slot.SlotID];

            cSlot.WaitingBook.Remove(slot.ReservationID);

            if (cSlot.State == CalendarSlotState.ACKNOWLEDGED && cSlot.WaitingBook.Count == 0)
            {
                cSlot.State = CalendarSlotState.FREE;
            }
            else if (cSlot.State == CalendarSlotState.BOOKED && cSlot.ReservationID == slot.ReservationID)
            {
                if (cSlot.WaitingBook.Count > 0)
                {
                    cSlot.State = CalendarSlotState.ACKNOWLEDGED;
                }
                else
                {
                    cSlot.State = CalendarSlotState.FREE;
                }
                cSlot.Locked = false;
            }
        }
예제 #16
0
        //Verify calendar slots and create reservation states
        private List<ReservationSlot> CreateReservationSlots(ReservationRequest req, int resID)
        {
            List<ReservationSlot> reservationSlots = new List<ReservationSlot>();

            foreach (int slot in req.Slots)
            {
                ReservationSlotState state = ReservationSlotState.INITIATED;

                CalendarSlot calendarSlot;
                if (_calendar.TryGetValue(slot, out calendarSlot))
                {
                    if (calendarSlot.State == CalendarSlotState.ASSIGNED)
                    {
                        state = ReservationSlotState.ABORTED;
                    }
                }
                else
                {
                    calendarSlot = new CalendarSlot();
                    calendarSlot.SlotNum = slot;
                    calendarSlot.State = CalendarSlotState.FREE;

                    _calendar[slot] = calendarSlot;
                    Log.Debug(_userName, "Creating new calendar entry. Slot: " + calendarSlot.SlotNum + ". State: " + calendarSlot.State);
                }

                Monitor.Enter(calendarSlot);
                if (calendarSlot.State == CalendarSlotState.FREE)
                {
                    calendarSlot.State = CalendarSlotState.ACKNOWLEDGED;
                }
                Monitor.Exit(calendarSlot);
                calendarSlot.WaitingBook.Add(resID);

                ReservationSlot rs = new ReservationSlot(resID, slot, state);
                reservationSlots.Add(rs);
            }

            return reservationSlots;
        }
예제 #17
0
 /*
  * CALENDAR SHOULD BE LOCKED BEFORE CALLING THIS METHOD
  */
 private void BookCalendarSlot(Reservation res, ReservationSlot resSlot)
 {
     CalendarSlot calendarSlot = _calendar[resSlot.SlotID];
     calendarSlot.WaitingBook.Remove(resSlot.ReservationID);
     res.CurrentSlot = resSlot.SlotID;
     calendarSlot.State = CalendarSlotState.BOOKED;
     calendarSlot.ReservationID = resSlot.ReservationID;
     resSlot.State = ReservationSlotState.TENTATIVELY_BOOKED;
 }
예제 #18
0
        /*
         * CALENDAR SHOULD BE LOCKED BEFORE CALLING THIS METHOD
         */
        private void AssignCalendarSlot(Reservation res, ReservationSlot resSlot, bool clean)
        {
            //Change calendar and reservation slot states
            CalendarSlot calendarSlot = _calendar[resSlot.SlotID];
            calendarSlot.State = CalendarSlotState.ASSIGNED;
            calendarSlot.ReservationID = res.ReservationID;
            calendarSlot.Participants = res.Participants;
            calendarSlot.Description = res.Description;

            foreach (ReservationSlot slot in res.Slots)
            {
                if (slot != resSlot && slot.State != ReservationSlotState.ABORTED)
                {
                    AbortReservationSlot(slot, true);
                }
            }

            if (clean)
            {
                CleanReservation(res);
            }
        }
예제 #19
0
        private void AbortReservationSlot(ReservationSlot slot, bool locked)
        {
            Log.Debug(_userName, "Aborting slot " + slot.SlotID + " from reservation " + slot.ReservationID);

            if (slot != null)
            {
                slot.State = ReservationSlotState.ABORTED;
            }

            //IF NOT LOCKED GET LOCK HERE

            if (!locked)
            {
                Monitor.Enter(_calendar[slot.SlotID]);
            }

            FreeCalendarSlot(slot);

            if (!locked)
            {
                Monitor.Exit(_calendar[slot.SlotID]);
            }

            //IF NOT LOCKED RELEASE LOCK HERE
        }