Skip to content

Introduction

Simulator architecture

gradysim.simulator.handler

The Simulator and EventLoop provide the backbone upon which handlers implement functionalities into the simulation. In principle handlers are classes that have access to the event loop of the simulation and to it's nodes.

Handlers are registered during the building of the simulation, they are associated with a label and providers can access them through this label. Protocols can access them indirectly through the providers. Handlers can also have indirect effect on protocols indirectly since they have access to the encapsulated network node.

Every handler implements the IHandler interface.

gradysim.simulator.handler.interface.INodeHandler

Bases: ABC

The common interface every handler should implement.

Source code in gradysim/simulator/handler/interface.py
class INodeHandler(ABC):
    """
    The common interface every handler should implement.
    """

    @staticmethod
    @abstractmethod
    def get_label() -> str:
        """
        Static method returning the unique label of the handler. 
        If two handlers with the same label are registered only the last registered one will be accessible in the simulation.

        Returns:
            The unique label of this handler
        """
        pass

    @abstractmethod
    def inject(self, event_loop: EventLoop) -> None:
        """
        This function is called when the simulator is instantiated to provide the handler with the simulation's
        event loop.

        Args:
            event_loop: The simulation's event loop instance
        """
        pass

    def initialize(self) -> None:
        """
        This is called after the simulation is initialized. Useful if the handler implements some functionality
        that depends on running code at the beginning of the simulation.
        """
        pass

    def after_simulation_step(self, iteration: int, timestamp: float) -> None:
        """
        This callback function is called after every simulation step. Useful if the handler implements some 
        functionality that depends on running code at every step of the simulation.

        Args:
            iteration: Number of the iteration currently being ran
            timestamp: Current simulation timestamp in seconds
        """
        pass

    @abstractmethod
    def register_node(self, node: Node) -> None:
        """
        This is called after a node is added to the simulation's build process. The encapsulated node is
        passed as an argument.

        Args:
            node: Encapsulated node instance added to the simulation
        """
        pass

    def finalize(self) -> None:
        """
        This is called after the simulation is finished. Useful if the handler implements some functionality
        that depends on running code at the end of the simulation.
        """
        pass

after_simulation_step(iteration, timestamp)

This callback function is called after every simulation step. Useful if the handler implements some functionality that depends on running code at every step of the simulation.

Parameters:

Name Type Description Default
iteration int

Number of the iteration currently being ran

required
timestamp float

Current simulation timestamp in seconds

required
Source code in gradysim/simulator/handler/interface.py
def after_simulation_step(self, iteration: int, timestamp: float) -> None:
    """
    This callback function is called after every simulation step. Useful if the handler implements some 
    functionality that depends on running code at every step of the simulation.

    Args:
        iteration: Number of the iteration currently being ran
        timestamp: Current simulation timestamp in seconds
    """
    pass

finalize()

This is called after the simulation is finished. Useful if the handler implements some functionality that depends on running code at the end of the simulation.

Source code in gradysim/simulator/handler/interface.py
def finalize(self) -> None:
    """
    This is called after the simulation is finished. Useful if the handler implements some functionality
    that depends on running code at the end of the simulation.
    """
    pass

get_label() abstractmethod staticmethod

Static method returning the unique label of the handler. If two handlers with the same label are registered only the last registered one will be accessible in the simulation.

Returns:

Type Description
str

The unique label of this handler

Source code in gradysim/simulator/handler/interface.py
@staticmethod
@abstractmethod
def get_label() -> str:
    """
    Static method returning the unique label of the handler. 
    If two handlers with the same label are registered only the last registered one will be accessible in the simulation.

    Returns:
        The unique label of this handler
    """
    pass

initialize()

This is called after the simulation is initialized. Useful if the handler implements some functionality that depends on running code at the beginning of the simulation.

Source code in gradysim/simulator/handler/interface.py
def initialize(self) -> None:
    """
    This is called after the simulation is initialized. Useful if the handler implements some functionality
    that depends on running code at the beginning of the simulation.
    """
    pass

inject(event_loop) abstractmethod

This function is called when the simulator is instantiated to provide the handler with the simulation's event loop.

Parameters:

Name Type Description Default
event_loop EventLoop

The simulation's event loop instance

required
Source code in gradysim/simulator/handler/interface.py
@abstractmethod
def inject(self, event_loop: EventLoop) -> None:
    """
    This function is called when the simulator is instantiated to provide the handler with the simulation's
    event loop.

    Args:
        event_loop: The simulation's event loop instance
    """
    pass

register_node(node) abstractmethod

This is called after a node is added to the simulation's build process. The encapsulated node is passed as an argument.

Parameters:

Name Type Description Default
node Node

Encapsulated node instance added to the simulation

required
Source code in gradysim/simulator/handler/interface.py
@abstractmethod
def register_node(self, node: Node) -> None:
    """
    This is called after a node is added to the simulation's build process. The encapsulated node is
    passed as an argument.

    Args:
        node: Encapsulated node instance added to the simulation
    """
    pass