Module RelayModel.SortedListNode
Expand source code
import time
import traceback
from RelayModel.Node import Node
from RelayModel.RelayId import RelayId
class SortedListNodeState:
"""Holds all information needed to pass a state of the SortedListNode.
This class is needed to analyse a system of sorted list nodes. It gets send to the StateMonitor while simulating.
Attributes:
node_id (int): Holds the node id of the node.
left (StateRelay): Holds the relay which defines the connection of the left neighbor.
right (StateRelay): Holds the relay which defines the connection of the right neighbor.
relays (list): Holds a list of StateRelays which containing relays that are present in the underlying
RelayLayer.
running (bool): Holds the running status of the node.
leaving (bool): Holds the leaving status of the node.
"""
def __init__(self, node_id, left, right, relays, running, leaving):
"""When creating the state object all attributes must be set from the parameters.
Args:
node_id (int): Defines the node_id attribute.
left (StateRelay): Defines the left neighbor connection.
right (StateRelay): Defines the right neighbor connection.
relays (list): Defines the list of StateRelays.
running (bool): Defines the running state of the node.
leaving (bool): Defines the leaving state of the node.
"""
self.node_id = node_id
self.left = left
self.right = right
self.relays = relays
self.running = running
self.leaving = leaving
def __str__(self):
left = self.left.sink_rid if self.left is not None else 'None'
right = self.right.sink_rid if self.right is not None else 'None'
return "State: node_id={}, left={} " \
"right={} relays={}" \
"running={} leaving={}".format(self.node_id, left, right, self.relays, self.running, self.leaving)
class StateRelay:
"""Holds every information needed to analyse Relays.
This class is used to send Relay information to the StateMonitor. It should only be used in a State object.
Attributes:
relay_id (RelayId): Holds the RelayId of the Relay which information should be stored.
alive (bool): Holds the alive state of the Relay.
sink_rid (RelayLayerId): Holds the rid of the sink relay of the relay connection.
direct (bool): Holds the direct information of the Relay.
"""
def __init__(self, relay):
"""When creating a StateRelay object only a Relay object is needed.
From this Relay object all necessary information are extracted and stored into this class.
Args:
relay (Relay): The Relay object this StateRelay should represent.
"""
self.relay_id = relay.relay_id
self.alive = relay.alive
self.sink_rid = relay.sink_rid
self.direct = relay.is_direct()
class SortedListNode(Node):
"""The implementation of a sorted list node.
This class is an implementation of a sorted list protokoll. It is adjusted to work with the relay modell.
Attributes:
node_id (int): Holds the node id of the node to form a list topology.
left (RelayId): Holds the RelayId of the left neighbor Relay connection.
right (RelayId): Holds the RelayId of the right neighbor Relay connection.
"""
def __init__(self, node_id, ip: str, port: int, analyse_mode=False):
"""When creating a SortedListNode object every parameter from the Node class is needed.
Args:
node_id (int): Defines the node id of this specific node.
ip (str): Defines the ip address the node should be reachable on.
port (int): Defines the port the node should be reachable on.
analyse_mode (bool, optional): Whether the node should be executed in analyse mode or not.
"""
super(SortedListNode, self).__init__(node_id, ip, port, analyse_mode)
self.node_id = node_id
self.__left = None
self.__right = None
def __set_left(self, relay):
if relay is None:
self.logger.debug("REMOVE LEFT SET TO NONE")
self.__left = None
elif isinstance(relay, RelayId):
# print("Setting left relay", relay.relay_id)
self.__left = relay
self.relay_layer.validate_relay(relay)
def __get_left(self):
"""Handles the left neighbor attribute.
When setting the left neighbor it only accepts None or a RelayId as a value. When setting the neighbor the Relay
gets validated after setting.
"""
return self.__left
def __set_right(self, relay):
if relay is None:
self.logger.debug("REMOVE RIGHT SET TO NONE")
self.__right = None
elif isinstance(relay, RelayId):
# print("Setting right relay", relay.relay_id)
self.__right = relay
self.relay_layer.validate_relay(relay)
def __get_right(self):
"""Handles the right neighbor attribute.
When setting the right neighbor it only accepts None or a RelayId as a value. When setting the neighbor the
Relay gets validated after setting.
"""
return self.__right
left = property(__get_left, __set_left)
right = property(__get_right, __set_right)
def original_timeout(self):
"""Overrides the method from the node class to implement a BuildList protocol.
The method corrects left and right neighbors and introduces itself to them.
For further information see the thesis of this module.
"""
# print(self.node_id, list(
# map(lambda x: str(x.relay_id) + "->" + str(x.out_relay.out_id) if x is not None else "",
# self.get_relays_from_original_variables())))
self.logger.debug("{} \t ".format(self.node_id) +
"left: {}\t".format(str(self.left) + "->" + str(self.relay_layer.get_sink_node_id(self.left)) if self.left is not None else "None")+
"right: {}".format(str(self.right) + "->" + str(self.relay_layer.get_sink_node_id(self.right))if self.right is not None else "None"))
self.logger.debug(f"Original Timeout: left: {self.left} \n right: {self.right}")
if self.left is not None and isinstance(self.left, RelayId) and self.relay_layer.check_relay_exists(self.left):
if self.relay_layer.get_sink_node_id(self.left) < self.node_id:
self.logger.debug("Send via left ot")
self.call_method(self.left, 'linearize', [self.in_ref])
else:
# print("Timeout left else")
# print("Send via in_ref ot")
# self.call_method(self.in_ref, 'linearize', [self.left])
self.logger.debug("Remove left and linearize {}".format(self.left))
left = self.left
self.left = None
self.linearize(left)
if self.right is not None and isinstance(self.right, RelayId) and self.relay_layer.check_relay_exists(self.right):
if self.relay_layer.get_sink_node_id(self.right) > self.node_id:
self.logger.debug("Send via right ot")
self.call_method(self.right, 'linearize', [self.in_ref])
else:
# print("Timeout right else")
self.logger.debug("Remove right and linearize {}".format(self.right))
# self.call_method(self.in_ref, 'linearize', [self.right])
right = self.right
self.right = None
self.linearize(right)
def reversal_of_relay(self, relay_id: RelayId):
"""Overrides the method from the node class.
The reversal of a relay is given by sending a linearize action to the given relay with the in_ref as parameter.
Args:
relay_id (RelayId): Defines the Relay connection that should be reversed.
"""
# print(f"reversal on {relay.out_relay}")
self.logger.debug("Reversal sent over relay {} and in ref {}".format(relay_id, self.in_ref))
self.call_method(relay_id, 'linearize', [self.in_ref])
def check_in_original_variables(self, relay_id: RelayId):
"""Overrides the method from the node class.
It checks if the given RelayId is present in the left or right neighbor variable.
Args:
relay_id (RelayId): Defines the RelayId that should be checked.
Returns:
bool: True if the given RelayId is in one of the variables, False otherwise.
"""
if self.__left == relay_id:
return True
elif self.__right == relay_id:
return True
else:
return False
def remove_from_original_variables(self, relay_id: RelayId):
"""Overrides the method from the node class.
It removes the given RelayId from the left or right neighbor if they are set to this RelayId.
Args:
relay_id (RelayId): The RelayId that should be deleted from the variables.
"""
if self.left == relay_id:
self.left = None
elif self.right == relay_id:
self.right = None
def get_relays_from_original_variables(self):
"""Overrides the method from the node class.
It forms a list with the left and right neighbor and returns it.
Returns:
list: A list containing the left and right neighbor RelayIds. Or an empty list if none is set at the moment.
"""
return_list = []
if self.__left is not None:
return_list.append(self.__left)
if self.__right is not None:
return_list.append(self.__right)
return return_list
def send_analyse_state(self):
"""Overrides method from the node class.
Creates a SortedListNodeState with all information needed and sends it to the StateMonitor.
Returns:
bool: Returns the system state. True if system is valid, False otherwise.
"""
if self.left is not None and self.relay_layer.check_relay_exists(self.left):
left = StateRelay(self.relay_layer.get_relay_by_relay_id(self.left))
else:
left = None
if self.right is not None and self.relay_layer.check_relay_exists(self.right):
right = StateRelay(self.relay_layer.get_relay_by_relay_id(self.right))
else:
right = None
validated_relays = self.relay_layer.get_validated_relays()
state_relays = []
for relay_id in validated_relays:
relay = self.relay_layer.get_relay_by_relay_id(relay_id)
if relay is not None:
state_relays.append(StateRelay(relay))
node_state = SortedListNodeState(self.node_id, left, right, state_relays,
self.running, self.leaving)
return self.send_state_to_monitor(node_state)
def linearize(self, v: RelayId):
"""Impelements the linearize method from the BuildList protocol.
For further information see the thesis of this module.
Args:
v (RelayId): The connection that should be linearized.
"""
self.logger.debug(f"Linearize relay: {v}\n left: {self.left}\n right: {self.right}")
if v is None:
self.logger.warning("V is NONE")
return
v_node_id = self.relay_layer.get_sink_node_id(v)
if v_node_id is None:
return
v_level = self.relay_layer.get_level(v)
if self.left is not None and self.relay_layer.check_relay_exists(self.left):
left_node_id = self.relay_layer.get_sink_node_id(self.left)
if v_node_id < left_node_id:
self.call_method(self.left, 'linearize', [v])
self.relay_layer.validate_relay(v)
if left_node_id < v_node_id < self.node_id:
self.logger.debug("Send left via v")
self.call_method(v, 'linearize', [self.left])
self.left = v
self.logger.debug("Self left after sending v {}".format(self.left))
elif left_node_id == v_node_id and self.left != v:
self.logger.debug(f"Merge left: {self.left}\n v: {v}")
merged = self.relay_layer.merge([self.left, v])
if merged is not None:
self.logger.debug(f"Merged: {merged.relay_id} from {self.left} and {v}")
self.left = merged
else:
# self.logger.warning(f"Merged failed in node for {self.left} \nand {v}!!")
left_level = self.relay_layer.get_level(self.left)
if left_level is None or v_level < left_level:
left = self.left
self.left = v
self.relay_layer.delete(left)
else:
self.relay_layer.delete(v)
else:
if v_node_id < self.node_id:
self.logger.debug("Set left to v")
self.left = v
self.logger.debug("After set {}".format(self.left))
if self.right is not None and self.relay_layer.check_relay_exists(self.right):
right_node_id = self.relay_layer.get_sink_node_id(self.right)
if self.node_id < v_node_id < right_node_id:
self.logger.debug("Send right via v")
self.call_method(v, 'linearize', [self.right])
self.right = v
self.logger.debug("right after send {}".format(self.right))
elif right_node_id == v_node_id and self.right != v:
self.logger.debug(f"Merge right: {self.right}\n v: {v}")
merged = self.relay_layer.merge([self.right, v])
if merged is not None:
self.logger.debug(f"Merged: {merged} from {self.right} and {v}")
self.right = merged
else:
right_level = self.relay_layer.get_level(self.right)
if right_level is None or v_level < right_level:
right = self.right
self.right = v
self.relay_layer.delete(right)
else:
self.relay_layer.delete(v)
if right_node_id < v_node_id:
self.call_method(self.right, 'linearize', [v])
self.relay_layer.validate_relay(v)
else:
if self.node_id < v_node_id:
self.right = v
Classes
class SortedListNode (node_id, ip: str, port: int, analyse_mode=False)-
The implementation of a sorted list node.
This class is an implementation of a sorted list protokoll. It is adjusted to work with the relay modell.
Attributes
node_id:int- Holds the node id of the node to form a list topology.
left:RelayId- Holds the RelayId of the left neighbor Relay connection.
right:RelayId- Holds the RelayId of the right neighbor Relay connection.
When creating a SortedListNode object every parameter from the Node class is needed.
Args
node_id:int- Defines the node id of this specific node.
ip:str- Defines the ip address the node should be reachable on.
port:int- Defines the port the node should be reachable on.
analyse_mode:bool, optional- Whether the node should be executed in analyse mode or not.
Expand source code
class SortedListNode(Node): """The implementation of a sorted list node. This class is an implementation of a sorted list protokoll. It is adjusted to work with the relay modell. Attributes: node_id (int): Holds the node id of the node to form a list topology. left (RelayId): Holds the RelayId of the left neighbor Relay connection. right (RelayId): Holds the RelayId of the right neighbor Relay connection. """ def __init__(self, node_id, ip: str, port: int, analyse_mode=False): """When creating a SortedListNode object every parameter from the Node class is needed. Args: node_id (int): Defines the node id of this specific node. ip (str): Defines the ip address the node should be reachable on. port (int): Defines the port the node should be reachable on. analyse_mode (bool, optional): Whether the node should be executed in analyse mode or not. """ super(SortedListNode, self).__init__(node_id, ip, port, analyse_mode) self.node_id = node_id self.__left = None self.__right = None def __set_left(self, relay): if relay is None: self.logger.debug("REMOVE LEFT SET TO NONE") self.__left = None elif isinstance(relay, RelayId): # print("Setting left relay", relay.relay_id) self.__left = relay self.relay_layer.validate_relay(relay) def __get_left(self): """Handles the left neighbor attribute. When setting the left neighbor it only accepts None or a RelayId as a value. When setting the neighbor the Relay gets validated after setting. """ return self.__left def __set_right(self, relay): if relay is None: self.logger.debug("REMOVE RIGHT SET TO NONE") self.__right = None elif isinstance(relay, RelayId): # print("Setting right relay", relay.relay_id) self.__right = relay self.relay_layer.validate_relay(relay) def __get_right(self): """Handles the right neighbor attribute. When setting the right neighbor it only accepts None or a RelayId as a value. When setting the neighbor the Relay gets validated after setting. """ return self.__right left = property(__get_left, __set_left) right = property(__get_right, __set_right) def original_timeout(self): """Overrides the method from the node class to implement a BuildList protocol. The method corrects left and right neighbors and introduces itself to them. For further information see the thesis of this module. """ # print(self.node_id, list( # map(lambda x: str(x.relay_id) + "->" + str(x.out_relay.out_id) if x is not None else "", # self.get_relays_from_original_variables()))) self.logger.debug("{} \t ".format(self.node_id) + "left: {}\t".format(str(self.left) + "->" + str(self.relay_layer.get_sink_node_id(self.left)) if self.left is not None else "None")+ "right: {}".format(str(self.right) + "->" + str(self.relay_layer.get_sink_node_id(self.right))if self.right is not None else "None")) self.logger.debug(f"Original Timeout: left: {self.left} \n right: {self.right}") if self.left is not None and isinstance(self.left, RelayId) and self.relay_layer.check_relay_exists(self.left): if self.relay_layer.get_sink_node_id(self.left) < self.node_id: self.logger.debug("Send via left ot") self.call_method(self.left, 'linearize', [self.in_ref]) else: # print("Timeout left else") # print("Send via in_ref ot") # self.call_method(self.in_ref, 'linearize', [self.left]) self.logger.debug("Remove left and linearize {}".format(self.left)) left = self.left self.left = None self.linearize(left) if self.right is not None and isinstance(self.right, RelayId) and self.relay_layer.check_relay_exists(self.right): if self.relay_layer.get_sink_node_id(self.right) > self.node_id: self.logger.debug("Send via right ot") self.call_method(self.right, 'linearize', [self.in_ref]) else: # print("Timeout right else") self.logger.debug("Remove right and linearize {}".format(self.right)) # self.call_method(self.in_ref, 'linearize', [self.right]) right = self.right self.right = None self.linearize(right) def reversal_of_relay(self, relay_id: RelayId): """Overrides the method from the node class. The reversal of a relay is given by sending a linearize action to the given relay with the in_ref as parameter. Args: relay_id (RelayId): Defines the Relay connection that should be reversed. """ # print(f"reversal on {relay.out_relay}") self.logger.debug("Reversal sent over relay {} and in ref {}".format(relay_id, self.in_ref)) self.call_method(relay_id, 'linearize', [self.in_ref]) def check_in_original_variables(self, relay_id: RelayId): """Overrides the method from the node class. It checks if the given RelayId is present in the left or right neighbor variable. Args: relay_id (RelayId): Defines the RelayId that should be checked. Returns: bool: True if the given RelayId is in one of the variables, False otherwise. """ if self.__left == relay_id: return True elif self.__right == relay_id: return True else: return False def remove_from_original_variables(self, relay_id: RelayId): """Overrides the method from the node class. It removes the given RelayId from the left or right neighbor if they are set to this RelayId. Args: relay_id (RelayId): The RelayId that should be deleted from the variables. """ if self.left == relay_id: self.left = None elif self.right == relay_id: self.right = None def get_relays_from_original_variables(self): """Overrides the method from the node class. It forms a list with the left and right neighbor and returns it. Returns: list: A list containing the left and right neighbor RelayIds. Or an empty list if none is set at the moment. """ return_list = [] if self.__left is not None: return_list.append(self.__left) if self.__right is not None: return_list.append(self.__right) return return_list def send_analyse_state(self): """Overrides method from the node class. Creates a SortedListNodeState with all information needed and sends it to the StateMonitor. Returns: bool: Returns the system state. True if system is valid, False otherwise. """ if self.left is not None and self.relay_layer.check_relay_exists(self.left): left = StateRelay(self.relay_layer.get_relay_by_relay_id(self.left)) else: left = None if self.right is not None and self.relay_layer.check_relay_exists(self.right): right = StateRelay(self.relay_layer.get_relay_by_relay_id(self.right)) else: right = None validated_relays = self.relay_layer.get_validated_relays() state_relays = [] for relay_id in validated_relays: relay = self.relay_layer.get_relay_by_relay_id(relay_id) if relay is not None: state_relays.append(StateRelay(relay)) node_state = SortedListNodeState(self.node_id, left, right, state_relays, self.running, self.leaving) return self.send_state_to_monitor(node_state) def linearize(self, v: RelayId): """Impelements the linearize method from the BuildList protocol. For further information see the thesis of this module. Args: v (RelayId): The connection that should be linearized. """ self.logger.debug(f"Linearize relay: {v}\n left: {self.left}\n right: {self.right}") if v is None: self.logger.warning("V is NONE") return v_node_id = self.relay_layer.get_sink_node_id(v) if v_node_id is None: return v_level = self.relay_layer.get_level(v) if self.left is not None and self.relay_layer.check_relay_exists(self.left): left_node_id = self.relay_layer.get_sink_node_id(self.left) if v_node_id < left_node_id: self.call_method(self.left, 'linearize', [v]) self.relay_layer.validate_relay(v) if left_node_id < v_node_id < self.node_id: self.logger.debug("Send left via v") self.call_method(v, 'linearize', [self.left]) self.left = v self.logger.debug("Self left after sending v {}".format(self.left)) elif left_node_id == v_node_id and self.left != v: self.logger.debug(f"Merge left: {self.left}\n v: {v}") merged = self.relay_layer.merge([self.left, v]) if merged is not None: self.logger.debug(f"Merged: {merged.relay_id} from {self.left} and {v}") self.left = merged else: # self.logger.warning(f"Merged failed in node for {self.left} \nand {v}!!") left_level = self.relay_layer.get_level(self.left) if left_level is None or v_level < left_level: left = self.left self.left = v self.relay_layer.delete(left) else: self.relay_layer.delete(v) else: if v_node_id < self.node_id: self.logger.debug("Set left to v") self.left = v self.logger.debug("After set {}".format(self.left)) if self.right is not None and self.relay_layer.check_relay_exists(self.right): right_node_id = self.relay_layer.get_sink_node_id(self.right) if self.node_id < v_node_id < right_node_id: self.logger.debug("Send right via v") self.call_method(v, 'linearize', [self.right]) self.right = v self.logger.debug("right after send {}".format(self.right)) elif right_node_id == v_node_id and self.right != v: self.logger.debug(f"Merge right: {self.right}\n v: {v}") merged = self.relay_layer.merge([self.right, v]) if merged is not None: self.logger.debug(f"Merged: {merged} from {self.right} and {v}") self.right = merged else: right_level = self.relay_layer.get_level(self.right) if right_level is None or v_level < right_level: right = self.right self.right = v self.relay_layer.delete(right) else: self.relay_layer.delete(v) if right_node_id < v_node_id: self.call_method(self.right, 'linearize', [v]) self.relay_layer.validate_relay(v) else: if self.node_id < v_node_id: self.right = vAncestors
Instance variables
var left-
Handles the left neighbor attribute.
When setting the left neighbor it only accepts None or a RelayId as a value. When setting the neighbor the Relay gets validated after setting.
Expand source code
def __get_left(self): """Handles the left neighbor attribute. When setting the left neighbor it only accepts None or a RelayId as a value. When setting the neighbor the Relay gets validated after setting. """ return self.__left var right-
Handles the right neighbor attribute.
When setting the right neighbor it only accepts None or a RelayId as a value. When setting the neighbor the Relay gets validated after setting.
Expand source code
def __get_right(self): """Handles the right neighbor attribute. When setting the right neighbor it only accepts None or a RelayId as a value. When setting the neighbor the Relay gets validated after setting. """ return self.__right
Methods
def check_in_original_variables(self, relay_id: RelayId)-
Overrides the method from the node class.
It checks if the given RelayId is present in the left or right neighbor variable.
Args
relay_id:RelayId- Defines the RelayId that should be checked.
Returns
bool- True if the given RelayId is in one of the variables, False otherwise.
Expand source code
def check_in_original_variables(self, relay_id: RelayId): """Overrides the method from the node class. It checks if the given RelayId is present in the left or right neighbor variable. Args: relay_id (RelayId): Defines the RelayId that should be checked. Returns: bool: True if the given RelayId is in one of the variables, False otherwise. """ if self.__left == relay_id: return True elif self.__right == relay_id: return True else: return False def get_relays_from_original_variables(self)-
Overrides the method from the node class.
It forms a list with the left and right neighbor and returns it.
Returns
list- A list containing the left and right neighbor RelayIds. Or an empty list if none is set at the moment.
Expand source code
def get_relays_from_original_variables(self): """Overrides the method from the node class. It forms a list with the left and right neighbor and returns it. Returns: list: A list containing the left and right neighbor RelayIds. Or an empty list if none is set at the moment. """ return_list = [] if self.__left is not None: return_list.append(self.__left) if self.__right is not None: return_list.append(self.__right) return return_list def linearize(self, v: RelayId)-
Impelements the linearize method from the BuildList protocol.
For further information see the thesis of this module.
Args
v:RelayId- The connection that should be linearized.
Expand source code
def linearize(self, v: RelayId): """Impelements the linearize method from the BuildList protocol. For further information see the thesis of this module. Args: v (RelayId): The connection that should be linearized. """ self.logger.debug(f"Linearize relay: {v}\n left: {self.left}\n right: {self.right}") if v is None: self.logger.warning("V is NONE") return v_node_id = self.relay_layer.get_sink_node_id(v) if v_node_id is None: return v_level = self.relay_layer.get_level(v) if self.left is not None and self.relay_layer.check_relay_exists(self.left): left_node_id = self.relay_layer.get_sink_node_id(self.left) if v_node_id < left_node_id: self.call_method(self.left, 'linearize', [v]) self.relay_layer.validate_relay(v) if left_node_id < v_node_id < self.node_id: self.logger.debug("Send left via v") self.call_method(v, 'linearize', [self.left]) self.left = v self.logger.debug("Self left after sending v {}".format(self.left)) elif left_node_id == v_node_id and self.left != v: self.logger.debug(f"Merge left: {self.left}\n v: {v}") merged = self.relay_layer.merge([self.left, v]) if merged is not None: self.logger.debug(f"Merged: {merged.relay_id} from {self.left} and {v}") self.left = merged else: # self.logger.warning(f"Merged failed in node for {self.left} \nand {v}!!") left_level = self.relay_layer.get_level(self.left) if left_level is None or v_level < left_level: left = self.left self.left = v self.relay_layer.delete(left) else: self.relay_layer.delete(v) else: if v_node_id < self.node_id: self.logger.debug("Set left to v") self.left = v self.logger.debug("After set {}".format(self.left)) if self.right is not None and self.relay_layer.check_relay_exists(self.right): right_node_id = self.relay_layer.get_sink_node_id(self.right) if self.node_id < v_node_id < right_node_id: self.logger.debug("Send right via v") self.call_method(v, 'linearize', [self.right]) self.right = v self.logger.debug("right after send {}".format(self.right)) elif right_node_id == v_node_id and self.right != v: self.logger.debug(f"Merge right: {self.right}\n v: {v}") merged = self.relay_layer.merge([self.right, v]) if merged is not None: self.logger.debug(f"Merged: {merged} from {self.right} and {v}") self.right = merged else: right_level = self.relay_layer.get_level(self.right) if right_level is None or v_level < right_level: right = self.right self.right = v self.relay_layer.delete(right) else: self.relay_layer.delete(v) if right_node_id < v_node_id: self.call_method(self.right, 'linearize', [v]) self.relay_layer.validate_relay(v) else: if self.node_id < v_node_id: self.right = v def original_timeout(self)-
Overrides the method from the node class to implement a BuildList protocol.
The method corrects left and right neighbors and introduces itself to them. For further information see the thesis of this module.
Expand source code
def original_timeout(self): """Overrides the method from the node class to implement a BuildList protocol. The method corrects left and right neighbors and introduces itself to them. For further information see the thesis of this module. """ # print(self.node_id, list( # map(lambda x: str(x.relay_id) + "->" + str(x.out_relay.out_id) if x is not None else "", # self.get_relays_from_original_variables()))) self.logger.debug("{} \t ".format(self.node_id) + "left: {}\t".format(str(self.left) + "->" + str(self.relay_layer.get_sink_node_id(self.left)) if self.left is not None else "None")+ "right: {}".format(str(self.right) + "->" + str(self.relay_layer.get_sink_node_id(self.right))if self.right is not None else "None")) self.logger.debug(f"Original Timeout: left: {self.left} \n right: {self.right}") if self.left is not None and isinstance(self.left, RelayId) and self.relay_layer.check_relay_exists(self.left): if self.relay_layer.get_sink_node_id(self.left) < self.node_id: self.logger.debug("Send via left ot") self.call_method(self.left, 'linearize', [self.in_ref]) else: # print("Timeout left else") # print("Send via in_ref ot") # self.call_method(self.in_ref, 'linearize', [self.left]) self.logger.debug("Remove left and linearize {}".format(self.left)) left = self.left self.left = None self.linearize(left) if self.right is not None and isinstance(self.right, RelayId) and self.relay_layer.check_relay_exists(self.right): if self.relay_layer.get_sink_node_id(self.right) > self.node_id: self.logger.debug("Send via right ot") self.call_method(self.right, 'linearize', [self.in_ref]) else: # print("Timeout right else") self.logger.debug("Remove right and linearize {}".format(self.right)) # self.call_method(self.in_ref, 'linearize', [self.right]) right = self.right self.right = None self.linearize(right) def remove_from_original_variables(self, relay_id: RelayId)-
Overrides the method from the node class.
It removes the given RelayId from the left or right neighbor if they are set to this RelayId.
Args
relay_id:RelayId- The RelayId that should be deleted from the variables.
Expand source code
def remove_from_original_variables(self, relay_id: RelayId): """Overrides the method from the node class. It removes the given RelayId from the left or right neighbor if they are set to this RelayId. Args: relay_id (RelayId): The RelayId that should be deleted from the variables. """ if self.left == relay_id: self.left = None elif self.right == relay_id: self.right = None def reversal_of_relay(self, relay_id: RelayId)-
Overrides the method from the node class.
The reversal of a relay is given by sending a linearize action to the given relay with the in_ref as parameter.
Args
relay_id:RelayId- Defines the Relay connection that should be reversed.
Expand source code
def reversal_of_relay(self, relay_id: RelayId): """Overrides the method from the node class. The reversal of a relay is given by sending a linearize action to the given relay with the in_ref as parameter. Args: relay_id (RelayId): Defines the Relay connection that should be reversed. """ # print(f"reversal on {relay.out_relay}") self.logger.debug("Reversal sent over relay {} and in ref {}".format(relay_id, self.in_ref)) self.call_method(relay_id, 'linearize', [self.in_ref]) def send_analyse_state(self)-
Overrides method from the node class.
Creates a SortedListNodeState with all information needed and sends it to the StateMonitor.
Returns
bool- Returns the system state. True if system is valid, False otherwise.
Expand source code
def send_analyse_state(self): """Overrides method from the node class. Creates a SortedListNodeState with all information needed and sends it to the StateMonitor. Returns: bool: Returns the system state. True if system is valid, False otherwise. """ if self.left is not None and self.relay_layer.check_relay_exists(self.left): left = StateRelay(self.relay_layer.get_relay_by_relay_id(self.left)) else: left = None if self.right is not None and self.relay_layer.check_relay_exists(self.right): right = StateRelay(self.relay_layer.get_relay_by_relay_id(self.right)) else: right = None validated_relays = self.relay_layer.get_validated_relays() state_relays = [] for relay_id in validated_relays: relay = self.relay_layer.get_relay_by_relay_id(relay_id) if relay is not None: state_relays.append(StateRelay(relay)) node_state = SortedListNodeState(self.node_id, left, right, state_relays, self.running, self.leaving) return self.send_state_to_monitor(node_state)
Inherited members
class SortedListNodeState (node_id, left, right, relays, running, leaving)-
Holds all information needed to pass a state of the SortedListNode.
This class is needed to analyse a system of sorted list nodes. It gets send to the StateMonitor while simulating.
Attributes
node_id:int- Holds the node id of the node.
left:StateRelay- Holds the relay which defines the connection of the left neighbor.
right:StateRelay- Holds the relay which defines the connection of the right neighbor.
relays:list- Holds a list of StateRelays which containing relays that are present in the underlying RelayLayer.
running:bool- Holds the running status of the node.
leaving:bool- Holds the leaving status of the node.
When creating the state object all attributes must be set from the parameters.
Args
node_id:int- Defines the node_id attribute.
left:StateRelay- Defines the left neighbor connection.
right:StateRelay- Defines the right neighbor connection.
relays:list- Defines the list of StateRelays.
running:bool- Defines the running state of the node.
leaving:bool- Defines the leaving state of the node.
Expand source code
class SortedListNodeState: """Holds all information needed to pass a state of the SortedListNode. This class is needed to analyse a system of sorted list nodes. It gets send to the StateMonitor while simulating. Attributes: node_id (int): Holds the node id of the node. left (StateRelay): Holds the relay which defines the connection of the left neighbor. right (StateRelay): Holds the relay which defines the connection of the right neighbor. relays (list): Holds a list of StateRelays which containing relays that are present in the underlying RelayLayer. running (bool): Holds the running status of the node. leaving (bool): Holds the leaving status of the node. """ def __init__(self, node_id, left, right, relays, running, leaving): """When creating the state object all attributes must be set from the parameters. Args: node_id (int): Defines the node_id attribute. left (StateRelay): Defines the left neighbor connection. right (StateRelay): Defines the right neighbor connection. relays (list): Defines the list of StateRelays. running (bool): Defines the running state of the node. leaving (bool): Defines the leaving state of the node. """ self.node_id = node_id self.left = left self.right = right self.relays = relays self.running = running self.leaving = leaving def __str__(self): left = self.left.sink_rid if self.left is not None else 'None' right = self.right.sink_rid if self.right is not None else 'None' return "State: node_id={}, left={} " \ "right={} relays={}" \ "running={} leaving={}".format(self.node_id, left, right, self.relays, self.running, self.leaving) class StateRelay (relay)-
Holds every information needed to analyse Relays.
This class is used to send Relay information to the StateMonitor. It should only be used in a State object.
Attributes
relay_id:RelayId- Holds the RelayId of the Relay which information should be stored.
alive:bool- Holds the alive state of the Relay.
sink_rid:RelayLayerId- Holds the rid of the sink relay of the relay connection.
direct:bool- Holds the direct information of the Relay.
When creating a StateRelay object only a Relay object is needed.
From this Relay object all necessary information are extracted and stored into this class.
Args
relay:Relay- The Relay object this StateRelay should represent.
Expand source code
class StateRelay: """Holds every information needed to analyse Relays. This class is used to send Relay information to the StateMonitor. It should only be used in a State object. Attributes: relay_id (RelayId): Holds the RelayId of the Relay which information should be stored. alive (bool): Holds the alive state of the Relay. sink_rid (RelayLayerId): Holds the rid of the sink relay of the relay connection. direct (bool): Holds the direct information of the Relay. """ def __init__(self, relay): """When creating a StateRelay object only a Relay object is needed. From this Relay object all necessary information are extracted and stored into this class. Args: relay (Relay): The Relay object this StateRelay should represent. """ self.relay_id = relay.relay_id self.alive = relay.alive self.sink_rid = relay.sink_rid self.direct = relay.is_direct()