//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn public override void ReceiveHandling(BaseMessage message) /// /// \brief Receive handling. /// /// \brief #### Description. /// -# This method is activated when a new message arrived to the process /// -# The method processing is done according to theire arrival order /// -# If you want to change the order of processing save the messages In an OperationResult attribute /// and then when you want to activate it process it befor procesing the message that is given /// to this method as a parameter /// /// \brief #### Algorithm. /// /// \brief #### 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) { // Note - Remove the following lise because your algorithm does not need to operate // The base process algorithm // base.ReceiveHandling(message); ChandyLamportMessage.MessageTypes messageType = (ChandyLamportMessage.MessageTypes)message[ElementDictionaries.ElementAttributes].Value[BaseMessage.HeaderFieldKeys.MessageType].Value; int sourceProcessId = message[ElementDictionaries.ElementAttributes].Value[BaseMessage.HeaderFieldKeys.SourceProcess].Value; ChandyLamportChannel channel = (ChandyLamportChannel)InChannels().First( c => c[ElementDictionaries.ElementAttributes].Value[BaseChannel.ElementAttributeKeys.SourceProcess].Value == sourceProcessId); switch (messageType) { case ChandyLamportMessage.MessageTypes.BaseMessage: BaseMessageArrived(message, channel); break; case ChandyLamportMessage.MessageTypes.Marker: MarkerArrived(message, channel); break; case ChandyLamportMessage.MessageTypes.Report: ReportArrived(message); break; } UpdatePresentation(); }
private void BaseMessageArrived(BaseMessage message, ChandyLamportChannel channel) { bool markerArrivedFromChannel = channel[ElementDictionaries.OperationResults].Value[ChandyLamportChannel.OperationResultKeys.MarkerArrived].Value; bool recorded = OperationResults.Value[OperationResultKeys.Recorded].Value; if (!markerArrivedFromChannel && recorded) { channel.AddMessage(message); } }
private void MarkerArrived(BaseMessage marker, ChandyLamportChannel channel) { // Add the weight of the message to the weight of the process double messageWeight = marker.GetField(ChandyLamportMessage.FieldKeys.Weight).Value; OperationResults.Value[OperationResultKeys.Weight].Value += messageWeight; TakeSnapshot(marker); // Termination condition channel[ElementDictionaries.OperationResults].Value[ChandyLamportChannel.OperationResultKeys.MarkerArrived].Value = true; if (InChannels().All(c => c[ElementDictionaries.OperationResults].Value[ChandyLamportChannel.OperationResultKeys.MarkerArrived].Value)) { bool initiator = ElementAttributes.Value[BaseProcess.ElementAttributeKeys.Initiator].Value; if (!initiator) { Report(); } } }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// \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) { ChandyLamportChannel channel = (ChandyLamportChannel)ChannelFrom(message); switch (message[bm.pak.MessageType]) { case m.MessageTypes.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 (or[p.ork.Recordered] && !channel.or[c.ork.Marker]) { channel.or[c.ork.State].Add(message[bm.ork.MessageName]); } break; case m.MessageTypes.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) or[p.ork.Weight] += message[m.marker.Weight]; TakeSnapshot(); // Check if the round ended (Received Marker from all it's neighbors) // Perform EndSnapshot (Send Report, reset variables) channel.or[c.ork.Marker] = true; if (InChannels.All(cnl => cnl.or[c.ork.Marker])) { EndSnapshot(); } break; case m.MessageTypes.Report: // If received a Report Message // If this is not the first report from the source processor in this round // throw the message if (message[bm.pak.Round] < or[bp.ork.Round] || ((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.Weight]; 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; } }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn public ChandyLamportMessage(ChandyLamportNetwork network, object messageType, ChandyLamportChannel channel, string messageName, int round = 0, int logicalClock = 0): base(network, messageType, channel, messageName, round, logicalClock) /// /// \brief Constructor. /// /// \par Description. /// Construct a message from header parameters. /// /// \par Algorithm. /// /// \par Usage Notes. /// /// \author Ilanh /// \date 14/03/2017 /// /// \param network (ChandyLamportNetwork) - The network. /// \param messageType (dynamic) - Type of the message. /// \param channel (ChandyLamportChannel) - The channel. /// \param messageName (string) - Name of the message. /// \param round (Optional) (int) - The round. /// \param logicalClock (Optional) (int) - The logical clock. /// //////////////////////////////////////////////////////////////////////////////////////////////////// public ChandyLamportMessage(ChandyLamportNetwork network, object messageType, ChandyLamportChannel channel, string messageName, int round = 0, int logicalClock = 0) : base(network, messageType, channel, messageName, round, logicalClock) { }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// \fn public ChandyLamportMessage(ChandyLamportMessage sourceMessage, ChandyLamportChannel sendingChannel): base(sourceMessage, sendingChannel) /// /// \brief Constructor. /// /// \par Description. /// A message that is duplicated to the source except for the channel parameters. /// /// \par Algorithm. /// /// \par Usage Notes. /// This constructor is useful when you want to forward a message to other channels /// /// \author Ilanh /// \date 14/03/2017 /// /// \param sourceMessage (ChandyLamportMessage) - Message describing the source. /// \param sendingChannel (ChandyLamportChannel) - The sending channel. //////////////////////////////////////////////////////////////////////////////////////////////////// public ChandyLamportMessage(ChandyLamportNetwork network, ChandyLamportMessage sourceMessage, ChandyLamportChannel sendingChannel) : base(network, sourceMessage, sendingChannel) { }