Пример #1
0
 def check_timer(self, eventobj: Event):
     current_time = datetime.datetime.now()
     delta = current_time - self.waiting_since
     if delta.seconds > self.timeout_duration:
         self.send_self(Event(self, FireWirePacketType.TIMEOUT, "..."))
     else:
         sleep(0.2)
         self.send_self(Event(self, FireWirePacketType.CHECK_TIMER, "..."))
Пример #2
0
    def on_message_from_bottom(self, eventobj: Event):
        applmessage = eventobj.eventcontent
        hdr = applmessage.header

        # print(f"Node-{self.componentinstancenumber}: Node-{hdr.messagefrom} has sent {hdr.messagetype} message (payload: {applmessage.payload})")

        if hdr.messagetype == ApplicationLayerMessageType.BASIC:
            self.basic_message_queue.put_nowait(applmessage)

            if self._in_tree:
                self.send_ack_control_message(hdr.messagefrom, False)
            else:
                self._parent_node = hdr.messagefrom
                self._in_tree = True

                if self.componentinstancenumber not in self.context["alive_nodes"]:
                    self.context["alive_nodes"].append(self.componentinstancenumber)
        elif hdr.messagetype == ApplicationLayerMessageType.CONTROL:
            # self.control_message_queue.put_nowait(applmessage)

            try:
                self._children.remove(hdr.messagefrom)
                self._child_counter -= 1
            except ValueError as e:
                # print(f"\n\n\n{self.componentinstancenumber}: {e} {hdr.messagefrom} {self._children}\n\n\n")
                pass
        elif hdr.messagetype == ApplicationLayerMessageType.WAVE:
            if applmessage.payload.messagepayload.tag == self.componentinstancenumber:
                self.my_wave_bucket.append(applmessage.payload.messagepayload.response)

                if WAVE_DEBUG:
                    print(f"  WAVE << N-{self.componentinstancenumber} << N-{hdr.messagefrom} ({applmessage.payload.messagepayload.response})")

                if len(self.my_wave_bucket) == (len(self.context["network"].G.nodes()) - 1):
                    if WAVE_DEBUG:
                        print(f"  ::: WAVE END >> N-{self.componentinstancenumber}: {' '.join(['A' if x == SFWaveResponse.ACTIVE else ('F' if x == SFWaveResponse.FINISHED else 'XXX') for x in self.my_wave_bucket])}")

                    if SFWaveResponse.ACTIVE not in self.my_wave_bucket:
                        print(f"  ::: WAVE END >> N-{self.componentinstancenumber}: ANNOUNCE!")
                        self.announce_on_next_tick = True
                    else:
                        print(f"  ::: WAVE END >> N-{self.componentinstancenumber}: NOT DONE YET!")
                        self.my_wave_bucket = []
            else:
                if self.__exited_from_tree:
                    self.send_down(Event(self, EventTypes.MFRT, self.prepare_application_layer_message(ApplicationLayerMessageType.WAVE, applmessage.payload.messagepayload.tag, SFWaveMessagePayload(applmessage.payload.messagepayload.tag, SFWaveMessageType.RESPONSE, SFWaveResponse.FINISHED))))
                    if WAVE_DEBUG:
                        print(f"  WAVE >> N-{self.componentinstancenumber} >> N-{applmessage.payload.messagepayload.tag} >> FINISHED")
                else:
                    self.send_down(Event(self, EventTypes.MFRT, self.prepare_application_layer_message(ApplicationLayerMessageType.WAVE, applmessage.payload.messagepayload.tag, SFWaveMessagePayload(applmessage.payload.messagepayload.tag, SFWaveMessageType.RESPONSE, SFWaveResponse.ACTIVE))))
                    if WAVE_DEBUG:
                        print(f"  WAVE >> N-{self.componentinstancenumber} >> N-{applmessage.payload.messagepayload.tag} >> ACTIVE")

                self._wms += 1
        else:
            print(f"\n!!! N-{self.componentinstancenumber}: GOT MSG UNIDENT: {hdr.messagetype}, FROM {hdr.messagefrom}")
            sys.exit(2)
Пример #3
0
 def on_tx_alive_message(self, eventobj: Event):
     time.sleep(self.alivemessageperiod)  # Period of alive messages
     # Send down the I'm Alive mesage
     # print("I am alive....")
     hdr = FailureDetectorMessageHeader(
         FailureDetectorMessageTypes.IAMALIVE, self.componentinstancenumber,
         MessageDestinationIdentifiers.LINKLAYERBROADCAST)
     payload = FailureDetectorMessagePayload(
         f"I am Node.{self.componentinstancenumber} and I am live ")
     failuredetectormessage = GenericMessage(hdr, payload)
     self.send_down(Event(self, EventTypes.MFRT, failuredetectormessage))
     # Schedule the next I'm Alive message
     self.send_self(Event(self, "txalivemessage",
                          "timer for alive message"))
Пример #4
0
    def on_message_from_bottom(self, eventobj: Event):
        """ New message from the link layer """
        header: FireWireMessageHeader = eventobj.eventcontent.header
        # paylaod is not important for FireWire

        if header.messagetype == FireWirePacketType.PARENT_REQ:
            if header.messagefrom is not self.parent:
                new_child = header.messagefrom

                self.received.append(new_child)

                next_hop_interface_id = f"{self.componentinstancenumber}-{new_child}"

                header = FireWireMessageHeader(
                    messagefrom=self.componentinstancenumber,
                    messageto=new_child,
                    nexthop=new_child,
                    messagetype=FireWirePacketType.ACKNOWLEDGEMENT,
                    interfaceid=next_hop_interface_id,
                )
                payload = FireWireMessagePayload()

                ack = GenericMessage(header, payload)
                self.send_down(Event(self, EventTypes.MFRT, ack))

                self.send_parent_req()
            elif not self.is_waiting:
                self.send_self(
                    Event(self, FireWirePacketType.ROOT_CONTENTION, "..."))
            else:
                print(
                    f" 👑 {self.componentinstancenumber} is elected as the leader"
                )
                self.is_leader = True
                self.is_terminated = True

        elif (header.messagetype == FireWirePacketType.ACKNOWLEDGEMENT
              and header.messagefrom == self.parent):
            # This node's parent request got acknowledged, the process can
            # safely terminate
            print(f"🤖 {self.componentinstancenumber} received an ACK "
                  f" from {header.messagefrom}, terminating")
            self.is_terminated = True
            self.in_root_contention = False

        self.callback.set()
        self.draw_delay.wait()
        self.draw_delay.clear()
Пример #5
0
 def start_traverse(self):
     token = self.create_token()
     self.send_self(
         Event(
             self, EventTypes.MFRB,
             self.prepare_message(DfsMessageTypes.START,
                                  self.componentinstancenumber, token, [])))
Пример #6
0
    def send_parent_req(self):
        """Send a parent request to the only eligible neighbour node. The
        neighbour node should not have sent this node a parent request and the
        number of such neighbours of this node should be 1.
        """
        # if there is *only* one possible parent then send them a parent request here

        result = self.neighbours - set(self.received)

        if len(result) == 1:
            par = result.pop()
            self.parent = par

            print(
                f"🤖 {self.componentinstancenumber} picked {self.parent} as it's parent"
            )

            next_hop_interface_id = f"{self.componentinstancenumber}-{self.parent}"

            header = FireWireMessageHeader(
                messagefrom=self.componentinstancenumber,
                messageto=self.parent,
                nexthop=self.parent,
                messagetype=FireWirePacketType.PARENT_REQ,
                interfaceid=next_hop_interface_id,
            )
            payload = FireWireMessagePayload()

            message = GenericMessage(header, payload)
            self.send_down(Event(self, EventTypes.MFRT, message))
        else:
            # Cannot send a parent request, more than one possible parent
            return
Пример #7
0
 def send_random_basic_message(self, to: int) -> None:
     self.send_down(
         Event(
             self, EventTypes.MFRT,
             self.prepare_application_layer_message(
                 ApplicationLayerMessageType.BASIC, to,
                 str(dt.now().timestamp()))))
Пример #8
0
    def call_wave(self):
        print(f"  > CALL WAVE @@ N-{self.componentinstancenumber}")

        to_nodes = [i for i in range(len(self.context["network"].G.nodes())) if i != self.componentinstancenumber]

        for to in to_nodes:
            self.send_down(Event(self, EventTypes.MFRT, self.prepare_application_layer_message(ApplicationLayerMessageType.WAVE, to, SFWaveMessagePayload(self.componentinstancenumber, SFWaveMessageType.REQUEST))))
            self._wms += 1
Пример #9
0
 def on_propose(self, eventobj: Event):
     destination = 1
     hdr = ApplicationLayerMessageHeader(
         ApplicationLayerMessageTypes.ACCEPT, self.componentinstancenumber,
         destination)
     payload = ApplicationLayerMessagePayload("23")
     proposalmessage = GenericMessage(hdr, payload)
     self.send_down(Event(self, EventTypes.MFRT, proposalmessage))
Пример #10
0
 def send_ack_control_message(self, to: int, is_dead: bool) -> None:
     # print(f"send_ack_control_message: N-{self.componentinstancenumber} ==> N-{to} ({self._parent_node}) : {'DEAD' if is_dead else 'PKG_RESP'}")
     self.send_down(
         Event(
             self, EventTypes.MFRT,
             self.prepare_application_layer_message(
                 ApplicationLayerMessageType.CONTROL, to,
                 str(dt.now().timestamp()))))
     self._cms += 1
Пример #11
0
 def send_reply(self, nodeID):
     self.sentReplyCount += 1
     nextHop = Topology().get_next_hop(self.componentinstancenumber, nodeID)
     interfaceID = f"{self.componentinstancenumber}-{nextHop}"
     header = RicartAgrawalaMessageHeader(RicartAgrawalaMessageTypes.REPLY,
                                          self.componentinstancenumber,
                                          nodeID, nextHop, interfaceID)
     payload = GenericMessagePayload(self.componentinstancenumber)
     message = GenericMessage(header, payload)
     self.send_down(Event(self, EventTypes.MFRT, message))
Пример #12
0
  def on_message_from_bottom(self, eventobj: Event):
    msg = eventobj.eventcontent
    hdr = msg.header
    payload = msg.payload

    if hdr.messageto == self.componentinstancenumber or hdr.messageto == MessageDestinationIdentifiers.NETWORKLAYERBROADCAST:  # Add if broadcast....
      self.send_up(Event(self, EventTypes.MFRB, payload))
      print(f"I received a message to {hdr.messageto} and I am {self.componentinstancenumber}")
    else:
      destination = hdr.messageto
      nexthop = Topology().get_next_hop(self.componentinstancenumber, destination)
      if nexthop != float('inf'):
        newhdr = NetworkLayerMessageHeader(NetworkLayerMessageTypes.NETMSG, self.componentinstancenumber, destination,
                                           nexthop)
        newpayload = eventobj.eventcontent.payload
        msg = GenericMessage(newhdr, newpayload)
        self.send_down(Event(self, EventTypes.MFRT, msg))
        print(f"{self.componentinstancenumber} will FORWARD a message to {destination} over {nexthop}")
      else:
        print(f"NO PATH {self.componentinstancenumber} will NOT FORWARD a message to {destination} over {nexthop}")
Пример #13
0
 def on_message_from_top(self, eventobj: Event):
   # if channelid != hdr.interfaceif then drop (should not be on this channel)
   hdr = eventobj.eventcontent.header
   if hdr.nexthop != MessageDestinationIdentifiers.LINKLAYERBROADCAST:
     if set(hdr.interfaceid.split("-")) == set(self.componentinstancenumber.split("-")):
       #print(f"Will forward message since {hdr.interfaceid} and {self.componentinstancenumber}")
       myevent = Event(eventobj.eventsource, ChannelEventTypes.INCH, eventobj.eventcontent)
       self.channelqueue.put_nowait(myevent)
     else:
       #print(f"Will drop message since {hdr.interfaceid} and {self.componentinstancenumber}")
       pass
Пример #14
0
    def reply_received(self, eventobj: Event):
        self.receivedReplyCount += 1
        replyFrom = eventobj.eventcontent.payload.messagepayload
        self.receivedReplies.add(replyFrom)

        if len(self.receivedReplies) == len(self.otherNodeIDs):
            self.send_self(
                Event(self, RicartAgrawalaEventTypes.PRIVILEGE, None))
        elif len(self.receivedReplies) > len(self.otherNodeIDs):
            raise RuntimeError(
                "Received reply message count exceeded expected limit!")
Пример #15
0
 def on_message_from_bottom(self, eventobj: Event):
     msg = eventobj.eventcontent
     hdr = msg.header
     payload = msg.payload
     if hdr.messageto == self.componentinstancenumber or hdr.messageto == MessageDestinationIdentifiers.LINKLAYERBROADCAST:
         self.send_up(
             Event(self, EventTypes.MFRB, payload, eventobj.fromchannel)
         )  # doing decapsulation by just sending the payload
     else:
         #      print(f"I am {self.componentinstancenumber} and dropping the {hdr.messagetype} message to {hdr.messageto}")
         # Physical layer is a broadcast medium, and hence will accept all messages. The link layer will drop those messages that are not for me
         pass
Пример #16
0
 def on_deliver_to_component(self, eventobj: Event):
   callername = eventobj.eventsource.componentinstancenumber
   for item in self.connectors:
     callees = self.connectors[item]
     for callee in callees:
       calleename = callee.componentinstancenumber
       # print(f"I am connected to {calleename}. Will check if I have to distribute it to {item}")
       if calleename == callername:
         pass
       else:
         myevent = Event(eventobj.eventsource, EventTypes.MFRB, eventobj.eventcontent, self.componentinstancenumber)
         callee.trigger_event(myevent)
Пример #17
0
    def on_message_from_bottom(self, eventobj: Event):
        message = eventobj.eventcontent
        header = message.header
        messageType = header.messagetype
        messageTo = header.messageto

        if messageTo == self.componentinstancenumber:
            if messageType == RicartAgrawalaMessageTypes.REQUEST:
                eventobj.event = RicartAgrawalaEventTypes.REQUEST
                self.send_self(eventobj)
            elif messageType == RicartAgrawalaMessageTypes.REPLY:
                eventobj.event = RicartAgrawalaEventTypes.REPLY
                self.send_self(eventobj)
        else:
            nextHop = Topology().get_next_hop(self.componentinstancenumber,
                                              messageTo)
            interfaceID = f"{self.componentinstancenumber}-{nextHop}"

            if nextHop != inf and nextHop != self.componentinstancenumber:
                self.forwardedMessageCount += 1
                header.nexthop = nextHop
                header.interfaceid = interfaceID
                self.send_down(Event(self, EventTypes.MFRT, message))
Пример #18
0
 def senddownbroadcast(self, eventobj: Event, whosends, sequencenumber):
     applmsg = eventobj.eventcontent
     destination = MessageDestinationIdentifiers.NETWORKLAYERBROADCAST
     nexthop = MessageDestinationIdentifiers.LINKLAYERBROADCAST
     print(
         f"{self.componentinstancenumber} will SEND a message to {destination} over {nexthop}"
     )
     hdr = BroadcastingMessageHeader(BroadcastingMessageTypes.SIMPLEFLOOD,
                                     whosends, destination, nexthop,
                                     sequencenumber)
     payload = applmsg
     broadcastmessage = GenericMessage(hdr, payload)
     self.send_down(Event(self, EventTypes.MFRT, broadcastmessage))
     self.broadcastdb.append(broadcastmessage.uniqueid)
Пример #19
0
 def on_message_from_top(self, eventobj: Event):
   # Encapsulate the SDU in network layer PDU
   applmsg = eventobj.eventcontent
   destination = applmsg.header.messageto
   nexthop = Topology().get_next_hop(self.componentinstancenumber, destination)
   if nexthop != float('inf'):
     print(f"{self.componentinstancenumber} will SEND a message to {destination} over {nexthop}")
     hdr = NetworkLayerMessageHeader(NetworkLayerMessageTypes.NETMSG, self.componentinstancenumber, destination,
                                     nexthop)
     payload = eventobj.eventcontent
     msg = GenericMessage(hdr, payload)
     self.send_down(Event(self, EventTypes.MFRT, msg))
   else:
     print(f"NO PATH: {self.componentinstancenumber} will NOTSEND a message to {destination} over {nexthop}")
Пример #20
0
    def on_message_from_bottom(self, eventobj: Event):
        msg = eventobj.eventcontent
        hdr = msg.header
        message_source = hdr.messagefrom

        payload: List[Any] = msg.payload.messagepayload

        if hdr.messagetype == WaveMessageTypes.FORWARD or hdr.messagetype == WaveMessageTypes.START:
            token = hdr.token
            if hdr.messagetype == WaveMessageTypes.START:
                self.token_parent_mapping[token] = -1

            parent_for_token = self.token_parent_mapping.get(token, None)
            if parent_for_token == None:
                self.token_parent_mapping[token] = message_source
                parent_for_token = message_source

            message = None
            next_target = None
            """
        Tarry's algorithm has 2 rules.
        1 - A process never forwards the token through the same channel twice.
        2 - A process only forwards the token to its parent when there is no other option.
      """
            uninvoked_neighbors = [
                n for n in self.get_neighbor_mapping_for_token(token)
                if n.invoked == False and n.id != parent_for_token
            ]
            if len(uninvoked_neighbors
                   ) > 0:  # If true, send to the available neighbor
                neigh = choice(uninvoked_neighbors)
                # neigh = uninvoked_neighbors[0]
                neigh.invoked = True
                next_target = neigh.id
            else:  # Else, send the token back to the parent
                if parent_for_token == -1:  # If I am the initiator, traversing is completed
                    print("->".join(payload))
                    print("TRAVERSING IS COMPLETED IN " + str(len(payload)) +
                          " hops")
                    print(f"Graph had {Topology().G.number_of_edges()} edges")
                    print(len(set(payload)))
                    return
                else:
                    next_target = parent_for_token
            payload.append(str(self.componentinstancenumber))
            message = self.prepare_message(WaveMessageTypes.FORWARD,
                                           next_target, token, payload)
            self.send_down(Event(self, EventTypes.MFRT, message))
Пример #21
0
    def send_request(self):
        self.sentRequestCount += 1
        self.havePendingRequest = True
        self.pendingRequestClock = self.clock

        for nodeID in self.otherNodeIDs:
            nextHop = Topology().get_next_hop(self.componentinstancenumber,
                                              nodeID)
            interfaceID = f"{self.componentinstancenumber}-{nextHop}"
            header = RicartAgrawalaMessageHeader(
                RicartAgrawalaMessageTypes.REQUEST,
                self.componentinstancenumber, nodeID, nextHop, interfaceID)
            payload = RicartAgrawalaMessagePayload(
                self.pendingRequestClock, self.componentinstancenumber)
            message = GenericMessage(header, payload)
            self.send_down(Event(self, EventTypes.MFRT, message))
Пример #22
0
 def on_message_from_bottom(self, eventobj: Event):
     msg = eventobj.eventcontent
     hdr = msg.header
     payload = msg.payload
     if hdr.messagetype == BroadcastingMessageTypes.SIMPLEFLOOD:
         if hdr.messageto == self.componentinstancenumber or hdr.messageto == MessageDestinationIdentifiers.NETWORKLAYERBROADCAST:  # Add if broadcast....
             if msg.uniqueid in self.broadcastdb:
                 pass  # we have already handled this flooded message
             else:
                 # Send to higher layers
                 self.update_topology()
                 self.send_up(Event(self, EventTypes.MFRB, payload))
                 # Also continue flooding once
                 time.sleep(random.randint(1, 3))
                 self.senddownbroadcast(
                     eventobj, eventobj.eventcontent.header.messagefrom,
                     eventobj.eventcontent.header.sequencenumber)
Пример #23
0
    def root_contention(self, eventobj: Event):
        if self.is_leader:
            return
        print(f"🤖 {self.componentinstancenumber} is in ROOT CONTENTION")
        decision = random.choice([True, False])

        if decision:
            print(f"🤖 {self.componentinstancenumber} decides to YIELD")
            self.in_root_contention = True
            self.send_parent_req()
            self.is_waiting = False
            self.waiting_since = None
        else:
            print(f"🤖 {self.componentinstancenumber} decides to HOLD")
            self.is_waiting = True
            self.in_root_contention = False
            self.send_self(Event(self, FireWirePacketType.START_TIMER, "..."))
Пример #24
0
    def on_init(self, eventobj: Event):
        print(
            f"Initializing {self.componentname}.{self.componentinstancenumber}"
        )

        if self.componentinstancenumber == 0:
            # destination = random.randint(len(Topology.G.nodes))
            destination = 1
            hdr = ApplicationLayerMessageHeader(
                ApplicationLayerMessageTypes.PROPOSE,
                self.componentinstancenumber, destination)
            payload = ApplicationLayerMessagePayload("23")
            proposalmessage = GenericMessage(hdr, payload)
            randdelay = random.randint(0, 5)
            time.sleep(randdelay)
            self.send_self(Event(self, "propose", proposalmessage))
        else:
            pass
Пример #25
0
    def on_message_from_top(self, eventobj: Event):
        abovehdr = eventobj.eventcontent.header
        if abovehdr.messageto == MessageDestinationIdentifiers.NETWORKLAYERBROADCAST:
            hdr = LinkLayerMessageHeader(
                LinkLayerMessageTypes.LINKMSG,
                self.componentinstancenumber,
                MessageDestinationIdentifiers.LINKLAYERBROADCAST,
                nexthop=MessageDestinationIdentifiers.LINKLAYERBROADCAST)
        else:
            #if we do not broadcast, use nexthop to determine interfaceid and set hdr.interfaceid
            myinterfaceid = str(self.componentinstancenumber) + "-" + str(
                abovehdr.nexthop)
            hdr = LinkLayerMessageHeader(LinkLayerMessageTypes.LINKMSG,
                                         self.componentinstancenumber,
                                         abovehdr.nexthop,
                                         nexthop=abovehdr.nexthop,
                                         interfaceid=myinterfaceid)

        payload = eventobj.eventcontent
        msg = GenericMessage(hdr, payload)
        self.send_down(Event(self, EventTypes.MFRT, msg))
Пример #26
0
 def on_message_from_bottom(self, eventobj: Event):
     self.send_up(Event(self, EventTypes.MFRB, eventobj.eventcontent))
Пример #27
0
 def on_message_from_top(self, eventobj: Event):
     self.send_down(Event(self, EventTypes.MFRT, eventobj.eventcontent))
Пример #28
0
 def on_init(self, eventobj: Event):
   evt = Event(self, EventTypes.MFRT, "A to lower layer")
   self.send_down(evt)
Пример #29
0
 def on_message_from_top(self, eventobj: Event):
   print(f"I am {self.componentname}, eventcontent={eventobj.eventcontent}")
   evt = Event(self, EventTypes.MFRB, "L to higher layer")
   self.send_up(evt)
Пример #30
0
 def on_message_from_top(self, eventobj: Event):
   print(f"I am {self.componentname}, eventcontent={eventobj.eventcontent}\n")
   evt = Event(self, EventTypes.MFRT, "N to lower layer")
   self.send_down(evt)