original_docstring: The connect process of the node with the meridian protocol.
          Waits for a new message to come in and distinguishes between the message types
          Type 1: Regular task message from client, node simply responses
          Type 2: Clostest node request from client, node triggers the probe event to discover closest node asynchronously
          Type 3: Probing response or request from other node, at response the own VivaldiPosition is updated, at request, a response is sent
          Type 4: Ping Request from other node, to ping the target in the recursive nearest node search
          Yields:
              simpy.Event: the incoming message in msg_pipe
              simpy.Event: the latency as a timeout
          
docstring: The connect process of the node with the meridian protocol.
  Waits for a new message to come in and distinguishes between the message types
  Type 1: Regular task message from client, node simply responses
  Type 2: Clostest node request from client, node triggers the probe event to discover closest node asynchronously
  Type 3: Probing response or request from other node, at response the own VivaldiPosition is updated, at request, a response is sent
  Type 4: Ping Request from other node, to ping the target in the recursive nearest node search
docstring_tokens: The connect process of the node with the meridian protocol . Waits for a new message to come in and distinguishes between the message types Type 1 : Regular task message from client node simply responses Type 2 : Clostest node request from client node triggers the probe event to discover closest node asynchronously Type 3 : Probing response or request from other node at response the own VivaldiPosition is updated at request a response is sent Type 4 : Ping Request from other node to ping the target in the recursive nearest node search
code: def meridian_connect(self):
          """The connect process of the node with the meridian protocol.
          Waits for a new message to come in and distinguishes between the message types
          Type 1: Regular task message from client, node simply responses
          Type 2: Clostest node request from client, node triggers the probe event to discover closest node asynchronously
          Type 3: Probing response or request from other node, at response the own VivaldiPosition is updated, at request, a response is sent
          Type 4: Ping Request from other node, to ping the target in the recursive nearest node search
          Yields:
              simpy.Event: the incoming message in msg_pipe
              simpy.Event: the latency as a timeout
          """
          while True:
              in_msg = yield self.msg_pipe.get()
              start = time.perf_counter()
              self.in_msg_history.append(in_msg)
  
              if(in_msg.send_id == self.id):
                  print("I received a message from myself: ", in_msg)
                  continue
  
              sender = self.env.get_participant(in_msg.send_id)
              if self.verbose:
                  print("Node {}: {}".format(self.id, in_msg))
              # Update gossip
              self.update_gossip(in_msg)
              # Update Meridian if the sender is a fog Node
              if(isinstance(sender, FogNode)):
                  self.update_virtual_position(in_msg)
  
              # Message type 1 = Regular Message from client
              if(in_msg.msg_type == 1):
                  # check if client is a current client
                  current_client = next(
                      (client for client in self.clients if client.get('id') == in_msg.send_id), None)
                  # Update if client is already registered
                  if current_client:
                      current_client.update({'timestamp': self.env.now})
                  # Append to list if client is not already registered
                  elif len(self.clients) < self.slots:
                      self.clients.append(
                          {'id': in_msg.send_id, 'timestamp': self.env.now})
                  # if we have no capacity for the client we simply do not answer
                  else:
                      continue
                  out_msg = self.env.send_message(
                      self.id, in_msg.send_id, "Reply from node", gossip=self.gossip, response=True, prev_msg=in_msg, msg_type=1)
                  self.out_msg_history.append(out_msg)
  
              # Message type 2 = Node Request -> Trigger search for closest node
              elif(in_msg.msg_type == 2):
                  self.meridian_get_closest_node(in_msg)
  
              # Message type 3 = Network Probing -> update VivaldiPosition at response or respond at Request
              elif(in_msg.msg_type == 3):
                  # If it is an incoming ping from a Fog Node, just reply
                  if(isinstance(sender, FogNode) and not in_msg.prev_msg):
                      out_msg = self.env.send_message(
                          self.id, in_msg.send_id, "Probe reply from Node", gossip=self.gossip, response=True, prev_msg=in_msg, msg_type=3)
                      self.out_msg_history.append(out_msg)
  
                  # If it is an outgoing ping from Client look up the requester and forward the latency to the requester
                  elif(isinstance(sender, MobileClient)):
                      meridian_ping = next((ping for ping in self.meridian_pings if ping.get(
                          'target') == in_msg.send_id), None)
                      requester = meridian_ping.get('requester')
                      msg_body = {'latency': in_msg.latency,
                                  'target': in_msg.send_id}
                      out_msg = self.env.send_message(
                          self.id, requester, msg=msg_body, gossip=self.gossip, response=True, prev_msg=meridian_ping.get('msg'), msg_type=4)
                      self.out_msg_history.append(out_msg)
                      # Remove the ping information as it is no longer needed
                      self.meridian_pings.remove(meridian_ping)
  
              # Ping Request from other node, to ping the target
              elif(in_msg.msg_type == 4):
                  # Answer from node with ping information to target
                  if(in_msg.response):
                      target = in_msg.body.get('target')
                      d_latency = in_msg.body.get('latency')
                      request = next((request for request in self.meridian_requests if request.get(
                          'target') == target), None)
                      if request:
                          request.get('measures').append(
                              {'latency': d_latency, 'member': in_msg.send_id})
  
                  # Only take part in the probing process to a client if node still has the resscource for it
                  # By doing this we ensure no more clients are forwarded to this node
                  elif len(self.clients) < self.slots:
                      # Append ping information to short memory
                      target = in_msg.body.get('target')
                      self.meridian_pings.append(
                          {'msg_id': in_msg.id, 'requester': in_msg.send_id, 'target': target})
                      out_msg = self.env.send_message(
                          self.id, in_msg.body.get('target'), msg="Ping from Node", gossip=self.gossip, msg_type=3)
                      self.out_msg_history.append(out_msg)
  
              else:
                  if self.verbose:
                      print("Node {} received unknown message type: {}".format(
                          self.id, in_msg.msg_type))
  
              self.connect_performance = time.perf_counter() - start
code_tokens: def meridian_connect ( self ) : while True : in_msg = yield self . msg_pipe . get ( ) start = time . perf_counter ( ) self . in_msg_history . append ( in_msg ) if ( in_msg . send_id == self . id ) : print ( "I received a message from myself: " , in_msg ) continue sender = self . env . get_participant ( in_msg . send_id ) if self . verbose : print ( "Node {}: {}" . format ( self . id , in_msg ) ) self . update_gossip ( in_msg ) if ( isinstance ( sender , FogNode ) ) : self . update_virtual_position ( in_msg ) if ( in_msg . msg_type == 1 ) : current_client = next ( ( client for client in self . clients if client . get ( 'id' ) == in_msg . send_id ) , None ) if current_client : current_client . update ( { 'timestamp' : self . env . now } ) elif len ( self . clients ) < self . slots : self . clients . append ( { 'id' : in_msg . send_id , 'timestamp' : self . env . now } ) else : continue out_msg = self . env . send_message ( self . id , in_msg . send_id , "Reply from node" , gossip = self . gossip , response = True , prev_msg = in_msg , msg_type = 1 ) self . out_msg_history . append ( out_msg ) elif ( in_msg . msg_type == 2 ) : self . meridian_get_closest_node ( in_msg ) elif ( in_msg . msg_type == 3 ) : if ( isinstance ( sender , FogNode ) and not in_msg . prev_msg ) : out_msg = self . env . send_message ( self . id , in_msg . send_id , "Probe reply from Node" , gossip = self . gossip , response = True , prev_msg = in_msg , msg_type = 3 ) self . out_msg_history . append ( out_msg ) elif ( isinstance ( sender , MobileClient ) ) : meridian_ping = next ( ( ping for ping in self . meridian_pings if ping . get ( 'target' ) == in_msg . send_id ) , None ) requester = meridian_ping . get ( 'requester' ) msg_body = { 'latency' : in_msg . latency , 'target' : in_msg . send_id } out_msg = self . env . send_message ( self . id , requester , msg = msg_body , gossip = self . gossip , response = True , prev_msg = meridian_ping . get ( 'msg' ) , msg_type = 4 ) self . out_msg_history . append ( out_msg ) self . meridian_pings . remove ( meridian_ping ) elif ( in_msg . msg_type == 4 ) : if ( in_msg . response ) : target = in_msg . body . get ( 'target' ) d_latency = in_msg . body . get ( 'latency' ) request = next ( ( request for request in self . meridian_requests if request . get ( 'target' ) == target ) , None ) if request : request . get ( 'measures' ) . append ( { 'latency' : d_latency , 'member' : in_msg . send_id } ) elif len ( self . clients ) < self . slots : target = in_msg . body . get ( 'target' ) self . meridian_pings . append ( { 'msg_id' : in_msg . id , 'requester' : in_msg . send_id , 'target' : target } ) out_msg = self . env . send_message ( self . id , in_msg . body . get ( 'target' ) , msg = "Ping from Node" , gossip = self . gossip , msg_type = 3 ) self . out_msg_history . append ( out_msg ) else : if self . verbose : print ( "Node {} received unknown message type: {}" . format ( self . id , in_msg . msg_type ) ) self . connect_performance = time . perf_counter ( ) - start
short_docstring: The connect process of the node with the meridian protocol.
short_docstring_tokens: The connect process of the node with the meridian protocol .
comment: """The connect process of the node with the meridian protocol.
          Waits for a new message to come in and distinguishes between the message types
          Type 1: Regular task message from client, node simply responses
          Type 2: Clostest node request from client, node triggers the probe event to discover closest node asynchronously
          Type 3: Probing response or request from other node, at response the own VivaldiPosition is updated, at request, a response is sent
          Type 4: Ping Request from other node, to ping the target in the recursive nearest node search
          Yields:
              simpy.Event: the incoming message in msg_pipe
              simpy.Event: the latency as a timeout
          """$SEP$# Update gossip
  $SEP$# Update Meridian if the sender is a fog Node
  $SEP$# Message type 1 = Regular Message from client
  $SEP$# check if client is a current client
  $SEP$# Update if client is already registered
  $SEP$# Append to list if client is not already registered
  $SEP$# if we have no capacity for the client we simply do not answer
  $SEP$# Message type 2 = Node Request -> Trigger search for closest node
  $SEP$# Message type 3 = Network Probing -> update VivaldiPosition at response or respond at Request
  $SEP$# If it is an incoming ping from a Fog Node, just reply
  $SEP$# If it is an outgoing ping from Client look up the requester and forward the latency to the requester
  $SEP$# Remove the ping information as it is no longer needed
  $SEP$# Ping Request from other node, to ping the target
  $SEP$# Answer from node with ping information to target
  $SEP$# Only take part in the probing process to a client if node still has the resscource for it
  $SEP$# By doing this we ensure no more clients are forwarded to this node
  $SEP$# Append ping information to short memory
  