////////////////////////////////////////////////////////////////////////////////////////////////////
        /// \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;
            }
        }
Exemplo n.º 5
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// \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)
        {
        }
Exemplo n.º 6
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// \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)
        {
        }