Source code for eclypse.remote.bootstrap.bootstrap

# pylint: disable=import-outside-toplevel
"""Module for the RemoteBootstrap class.

It contains the configuration for the remote infrastructure.
"""

from __future__ import annotations

from dataclasses import (
    dataclass,
    field,
)
from importlib import import_module
from typing import (
    TYPE_CHECKING,
    Any,
)

from eclypse.remote import ray_backend

from .options_factory import RayOptionsFactory

if TYPE_CHECKING:
    from eclypse.graph.infrastructure import Infrastructure
    from eclypse.remote._node import RemoteNode
    from eclypse.simulation._simulator.remote import RemoteSimulator
    from eclypse.simulation.config import SimulationConfig


[docs] @dataclass(slots=True, init=False) class RemoteBootstrap: """Configuration for the remote infrastructure.""" _sim_class: type[Any] = field(repr=False) _node_class: type[Any] = field(repr=False) ray_options_factory: RayOptionsFactory env_vars: dict[str, str] node_args: dict[str, Any]
[docs] def __init__( self, sim_class: type[RemoteSimulator] | None = None, node_class: type[RemoteNode] | None = None, ray_options_factory: RayOptionsFactory | None = None, **node_args, ): """Create a new RemoteBootstrap. Args: sim_class (type[RemoteSimulator] | None): The remote simulator class. node_class (type[RemoteNode] | None): The remote node class. ray_options_factory (RayOptionsFactory | None): The Ray options factory. **node_args: The arguments for the remote node. """ self._sim_class = sim_class or _get_default_remote_simulator_class() self._node_class = node_class or _get_default_remote_node_class() self.ray_options_factory = ( ray_options_factory if ray_options_factory else RayOptionsFactory() ) self.env_vars = {} self.node_args = node_args
[docs] def build( self, infrastructure: Infrastructure, simulation_config: SimulationConfig | None = None, ): """Build the remote simulation.""" ray_backend.init(runtime_env={"env_vars": self.env_vars}) remote_nodes = [ _create_remote( f"{infrastructure.id}/{node}", self._node_class, self.ray_options_factory, node, infrastructure.id, ) for node in infrastructure.nodes ] return _create_remote( f"{infrastructure.id}/manager", self._sim_class, self.ray_options_factory, infrastructure, simulation_config, remotes=remote_nodes, )
def _create_remote( name: str, remote_cls: type[Any], options_factory: RayOptionsFactory, *args, **kwargs, ) -> Any: """Create a remote object. Args: name (str): The name of the remote object. remote_cls (Any): The class of the remote object. options_factory (RayOptionsFactory): The Ray options factory. *args: The arguments for the remote object. **kwargs: The keyword arguments for the remote object. Returns: Any: The remote object. """ return ( ray_backend.remote(remote_cls) .options(**options_factory(name)) .remote(*args, **kwargs) ) def _get_default_remote_simulator_class() -> type[Any]: """Return the default remote simulator class.""" return import_module("eclypse.simulation._simulator").RemoteSimulator def _get_default_remote_node_class() -> type[Any]: """Return the default remote node class.""" return import_module("eclypse.remote._node").RemoteNode