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