//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn private void EndSnapshot() /// /// \brief Ends a snapshot. /// /// \par Description. /// This message is sent after receiving Marker from all the neighbors /// /// \par Algorithm. /// /// /// \par Usage Notes. /// /// \author Ilanh /// \date 21/01/2018 //////////////////////////////////////////////////////////////////////////////////////////////////// private void EndSnapshot() { // If the process is the initiator - save the snapshot to the results if (Initiator) { Results.Add(RecordSnapshot()); } // If the process is not the initiator - Send a report and clear the weight else { SendReport(MessageDataFor_Report(bm.PrmSource.Prms, null, Id, RecordSnapshot(), Weight)); Weight = 0; } // Set the self Id to the list of source processes (in order to block report message coming // from this processor (If it is in a circle) ReceivedMessageFrom.Add(Id); // Init the algorithm flags and variables for the next round snapshot Recorderd = false; Snapshot = "Not Set"; foreach (ChandyLamport_NewStyleChannel cnl in InChannels) { cnl.Recorderd = false; cnl.State.Clear(); } }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn public override void ReceiveHandling(BaseMessage message) /// /// \brief Receive handling. /// /// \par Description. /// -# This method is activated when a new message arrived to the process /// -# The method processing is done according to their arrival order /// -# If you want to change the order of processing use the ArrangeMessageQ /// /// \par Algorithm. /// /// \par Usage Notes. /// Usually the algorithm of this method is: /// -# if message type is ... perform ... /// -# if message type is ... perform ... /// /// \author Ilan Hindy /// \date 26/01/2017 /// /// \param message The message. //////////////////////////////////////////////////////////////////////////////////////////////////// //public override void ReceiveHandling(BaseMessage message) //{ //ChandyLamport_NewStyleChannel channel = (ChandyLamport_NewStyleChannel)ChannelFrom(message); //ChandyLamport_NewStyleMessage msg = message as ChandyLamport_NewStyleMessage; //switch ((msg.MessageType) //{ // case BaseMessage: // // If the process performed snapshot but still did not get marker from all // // it's neighbors : // // Save the message - It will be sent as message in the channels // if (Recordered && !channel.Recorderd) // { // channel.State.Add(msg.Name); // } // break; // case (int)Marker: // // If the process received a marker: // // Add the weight in the marker // // Perform TakeSnapshot (If first Marker in round - Send Marker to all the neighbors) // Weight += msg.MarkerWeight; // TakeSnapshot(); // // Check if the round ended (Received Marker from all it's neighbors) // // Perform EndSnapshot (Send Report, reset variables) // channel.or[c.ork.Recorderd] = true; // if (InChannels.All(cnl => cnl.or[c.ork.Recorderd])) // { // EndSnapshot(); // } // // Change the text on the process because the weight changed // pp[bp.ppk.Text] = GetProcessDefaultName() + "\n" + or[p.ork.Weight]; // break; // case m.MessageTypes.Report: // // If received a Report Message // // If this is not the first report from the source processor in this round // // (or the previouse round because a report can come befor or after // // the marker throw the message // if (message[bm.pak.Round] < or[bp.ork.Round] - 1 || // ((AttributeList)or[p.ork.ReceivedMessageFrom]).Any((a => a.Value == (int)message[m.report.Id]))) // { // break; // } // else // { // or[p.ork.ReceivedMessageFrom].Add(message[m.report.Id]); // } // // If the process is the initiator // // Add the message to the results // // Add the weight to the process weight // // Check condition for end round (weight == 1) // // Check condition for end running (round = max rounds) // if (ea[bp.eak.Initiator]) // { // or[p.ork.Results].Add(message[m.report.Snapshot]); // or[p.ork.Weight] += message[m.report.ReportWeight]; // pp[bp.ppk.Text] = GetProcessDefaultName() + "\n" + or[p.ork.Weight]; // if (or[p.ork.Weight] == 1) // { // PrintResults(); // if (or[bp.ork.Round] < pa[p.pak.MaxRounds]) // { // TakeSnapshot(); // } // else // { // Terminate(); // } // } // } // // If the process is not the initiator // // Propagate the message to all the neighbors // else // { // SendToNeighbours(message, SelectingMethod.Exclude, new List<int> { (int)message[m.report.Id] }); // } // break; //} public override void ReceiveHandling(BaseMessage message) { ChandyLamport_NewStyleChannel channel = (ChandyLamport_NewStyleChannel)ChannelFrom(message); ChandyLamport_NewStyleMessage msg = null; msg = message as ChandyLamport_NewStyleMessage; switch (msg.MessageType) { case BaseMessage: // If the process performed snapshot but still did not get marker from all // it's neighbors : // Save the message - It will be sent as message in the channels if (Recorderd && !channel.Recorderd) { channel.State.Add(msg.Name); } break; case Marker: // If the process received a marker: // Add the weight in the marker // Perform TakeSnapshot (If first Marker in round - Send Marker to all the neighbors) Weight += msg.MarkerWeight; TakeSnapshot(); // Check if the round ended (Received Marker from all it's neighbors) // Perform EndSnapshot (Send Report, reset variables) channel.or[c.ork.Recorderd] = true; if (InChannels.All(cnl => ((ChandyLamport_NewStyleChannel)cnl).Recorderd)) { EndSnapshot(); } // Change the text on the process because the weight changed Text = GetProcessDefaultName() + "\n" + Weight; break; case Report: // If received a Report Message // If this is not the first report from the source processor in this round // (or the previouse round because a report can come befor or after // the marker throw the message if (msg.Round < Round - 1 || (ReceivedMessageFrom.Any(a => a.Value == msg.ReporterId))) { break; } else { ReceivedMessageFrom.Add(msg.ReporterId); } // If the process is the initiator // Add the message to the results // Add the weight to the process weight // Check condition for end round (weight == 1) // Check condition for end running (round = max rounds) if (Initiator) { Results.Add(msg.Snapshot); Weight += msg.ReportWeight; Text = GetProcessDefaultName() + "\n" + Weight; if (Weight == 1) { PrintResults(); if (Round < MaxRounds) { TakeSnapshot(); } else { Terminate(); } } } // If the process is not the initiator // Propagate the message to all the neighbors else { SendReport(MessageDataFor_Report(bm.PrmSource.Prms, null, msg.ReporterId, msg.Snapshot, msg.ReportWeight), SelectingMethod.Exclude, new List <int> { (int)msg.ReporterId }); //SendToNeighbours(msg, SelectingMethod.Exclude, new List<int> { (int)msg.ReporterId }); } break; } }