void IClientMonitor.MonitorReservation(Reservation res) { //Lock here res.ClientStubs = LookupUsers(res); //Unlock here _monitoredReservations[res.ReservationID] = res; }
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); } } } }
/* * 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; }
private ReservationSlot GetSlotAndAbortPredecessors(Reservation res, int slotID) { foreach (ReservationSlot slot in res.Slots) { if (slot.SlotID == slotID) { return slot; } else if (slot.State != ReservationSlotState.ABORTED) { AbortReservationSlot(slot, false); } } return null; }
private Reservation CreateReservation(ReservationRequest req, int resID, string initiatorID, string initiatorIP, int initiatorPort) { Reservation thisRes = new Reservation(); thisRes.ReservationID = resID; thisRes.Description = req.Description; thisRes.Participants = req.Users; thisRes.InitiatorID = initiatorID; thisRes.InitiatorIP = initiatorIP; thisRes.InitiatorPort = initiatorPort; return thisRes; }
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); } } }
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; }
private void CleanReservation(Reservation res) { //Remove from list of active reservations _activeReservations.Remove(res.ReservationID); _committedReservations[res.ReservationID] = res; }
/* * AUX METHODS */ private void BookNextSlot(Reservation res) { bool booked = false; //LOCK HERE foreach (ReservationSlot slot in res.Slots) { Monitor.Enter(_calendar[slot.SlotID]); CalendarSlot cSlot = _calendar[slot.SlotID]; if (slot.State != ReservationSlotState.ABORTED && !cSlot.Locked && (cSlot.State == CalendarSlotState.ACKNOWLEDGED || (cSlot.State == CalendarSlotState.BOOKED && res.ReservationID < cSlot.ReservationID))) { booked = true; BookCalendarSlot(res, slot); Monitor.Exit(_calendar[slot.SlotID]); Log.Show(_userName, "Starting book process of slot " + slot.SlotID + " from reservation " + res.ReservationID); foreach (string participantID in res.Participants) { if (!participantID.Equals(_userName)) { _msgDispatcher.SendMessage(MessageType.BOOK_SLOT, res.ReservationID, participantID, slot.SlotID); } } break; } else { Monitor.Exit(_calendar[slot.SlotID]); } } if (!booked) { Log.Show(_userName, "No available slots. Aborting reservation " + res.ReservationID); foreach (IBookingService client in res.ClientStubs.Values) { try { Log.Show(_userName, "Sending abort to client..."); AbortDelegate bookSlot = new AbortDelegate(client.AbortReservation); IAsyncResult RemAr = bookSlot.BeginInvoke(res.ReservationID, null, null); } catch (SocketException e) { Log.Show(_userName, "ERROR: Could not connect to client. Exception: " + e); } } AbortReservation(res.ReservationID); } }
/* * 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; }
/* * 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 static ReservationSlot GetSlot(Reservation res, int slotID) { foreach (ReservationSlot slot in res.Slots) { if (slot.SlotID == slotID) { return slot; } } return null; }
private Dictionary<string, IBookingService> LookupUsers(Reservation res) { Dictionary<string, IBookingService> onlineUsers = new Dictionary<string, IBookingService>(); foreach (string userID in res.Participants) { if (!userID.Equals(_userName)) { IBookingService client = LookupClientStub(userID); if (client != null) { _msgDispatch.ClientConnected(userID, client); onlineUsers[userID] = client; } } } return onlineUsers; }