/// <summary> /// Registers the given commit answer arrived from the given operator. /// </summary> /// <param name="commit">The arrived commit answer package.</param> /// <param name="senderID">The sender operator.</param> /// <returns>True in case of success, false otherwise.</returns> public bool RegisterCommitAnswer(RCPackage commitAw, int senderID) { if (!this.initialized) { throw new DssException("DssSimulationMgr is uninitialized!"); } /// If we are currently finishing the simulation --> do nothing if (this.hostLeft) { return(true); } if (commitAw == null || !commitAw.IsCommitted) { throw new ArgumentException("commitAw"); } if (senderID == this.root.IdOfThisPeer) { throw new DssException("Unexpected commit answer sender!"); } if (senderID < 0 || senderID >= this.root.OpCount) { throw new ArgumentException("senderID"); } if (commitAw.PackageFormat.ID != DssRoot.DSS_COMMIT_ANSWER) { /// Package format error. return(false); } int ticket = commitAw.ReadInt(0); if (!this.commitAwMonitors.ContainsKey(ticket)) { /// Unexpected ticket. return(false); } CommitMonitor monitor = this.commitAwMonitors[ticket]; int pingTime = -1; if (monitor.AnswerArrived(senderID, out pingTime)) { this.aptCalculators[senderID].NewItem(pingTime); if (monitor.IsCommitAnswered) { UnregisterCommitMonitor(ticket); } return(true); } else { /// Ping already answered by the sender. return(false); } }
/// <summary> /// Registers a CommitMonitor object with the given ticket. /// </summary> /// <param name="ticket">The ticket of the commit you want to register.</param> private void RegisterCommitMonitor(int ticket) { if (!this.initialized) { throw new DssException("DssSimulationMgr is uninitialized!"); } if (this.commitAwMonitors.ContainsKey(ticket)) { throw new DssException("Ticket " + ticket + " already registered!"); } int idOfThisPeer = this.root.IdOfThisPeer; bool otherOpExists = false; for (int i = 0; i < this.operatorFlags.Length; i++) { if (this.operatorFlags[i] && i != idOfThisPeer) { otherOpExists = true; break; } } if (otherOpExists) { AlarmClock awTimeoutClock = this.root.AlarmClkMgr.SetAlarmClock(DssRoot.Time + DssConstants.COMMIT_ANSWER_TIMEOUT, this.CommitAnswerTimeout); CommitMonitor monitor = new CommitMonitor(ticket, awTimeoutClock, this.root.IdOfThisPeer, this.root.OpCount, this.operatorFlags); if (monitor.IsCommitAnswered) { awTimeoutClock.Cancel(); } else { this.commitAwMonitors.Add(ticket, monitor); this.commitAwTimeouts.Add(awTimeoutClock, monitor); } } }
/// <summary> /// Unregisters the CommitMonitor object with the given ticket. /// </summary> /// <param name="ticket">The ticket of the commit you want to unregister.</param> private void UnregisterCommitMonitor(int ticket) { if (!this.initialized) { throw new DssException("DssSimulationMgr is uninitialized!"); } if (!this.commitAwMonitors.ContainsKey(ticket)) { throw new DssException("Ticket " + ticket + " is not registered!"); } CommitMonitor monitorToUnreg = this.commitAwMonitors[ticket]; if (!this.commitAwTimeouts.ContainsKey(monitorToUnreg.CommitAwTimeoutClock)) { throw new DssException("Timeout clock not found for monitor with ticket " + ticket + "!"); } monitorToUnreg.CommitAwTimeoutClock.Cancel(); this.commitAwMonitors.Remove(ticket); this.commitAwTimeouts.Remove(monitorToUnreg.CommitAwTimeoutClock); }