Infrastructure and Application(s)#
In ECLYPSE, both the infrastructure and applications are modelled as graphs enriched with resource-related attributes (assets) and dynamic behaviour (update policies). These are represented using two core classes:
Infrastructure– models a multi-layered infrastructure, made of nodes and links with their capabilitiesApplication– models a multi-service application, made of services and interactions with their requirements
The two classes share many structural similarities, but differ in purpose and in the parameters used at initialisation.
from eclypse import policies
from eclypse.graph.infrastructure import Infrastructure
infrastructure = Infrastructure(
infrastructure_id="infra",
include_default_assets=True,
update_policies=[
policies.failure.availability_flap(0.01, up_probability=0.2),
policies.distribution.uniform(
node_assets=["cpu", "ram"],
edge_assets=["latency", "bandwidth"],
node_distribution=(0.95, 1.05),
edge_distribution=(0.95, 1.05),
),
],
resource_init="min",
seed=42,
)
Key parameters:
infrastructure_id: identifier of the infrastructureupdate_policies: list of update policies for infrastructure resourcesnode_assets/edge_assets: available capabilities (asset values) of nodes and linksinclude_default_assets: include the built-in CPU, RAM, storage, availability, latency, and bandwidth assetsresource_init: initialisation of resources (min or max)seed: random seed for reproducibilitypath_assets_aggregators: aggregators for each link asset evaluation across paths
from eclypse import policies
from eclypse.graph.application import Application
application = Application(
application_id="app",
include_default_assets=True,
update_policies=[
policies.after(
50,
policies.degrade.reduce(
factor=0.6,
epochs=200,
node_assets=["cpu", "ram"],
edge_assets=["bandwidth"],
),
),
policies.after(
50,
policies.degrade.increase(
factor=1.6667,
epochs=200,
edge_assets=["latency"],
),
),
],
requirement_init="min",
seed=42,
flows=[["frontend", "worker"]],
)
Key parameters:
application_id: identifier of the application. Defaults to"Application"update_policies: list of update policies for application requirementsnode_assets/edge_assets: resource requirements (asset values) of services and linksinclude_default_assets: include the built-in requirement assetsrequirement_init: initialisation of resources (min or max)seed: random seed for reproducibilityflows: list of service chains or communication flows
These classes inherit from a common base (AssetGraph) and can be extended or composed via utility functions and default builders.
Defining the topologies#
Once you have defined an Infrastructure or an Application object, you can incrementally add nodes (or services) and edges (or interactions) to describe its structure.
Both classes expose two methods:
add_node()— to add a node or serviceadd_edge()— to add a link or interaction
These methods allow you to associate assets and automatically validate their values, according to the asset definitions you provided during initialisation.
from eclypse.graph.infrastructure import Infrastructure
from eclypse.graph.assets.defaults import cpu, ram, latency, bandwidth
infra = Infrastructure(
infrastructure_id="my-infra",
node_assets={"cpu": cpu, "ram": ram},
edge_assets={"latency": latency, "bandwidth": bandwidth},
)
# Add two compute node
infra.add_node("node-1", cpu=4.0, ram=8.0)
infra.add_node("node-2", cpu=8.0, ram=16.0, strict=False)
# Add a link with latency and bandwidth
infra.add_edge(
"node-1", "node-2",
latency=10.0,
bandwidth=100.0,
symmetric=True # optional bidirectional link
)
strict=True(default): raises an error if asset values are inconsistentsymmetric=True: adds the edge in both directions
from eclypse.graph.application import Application
from eclypse.graph.assets.defaults import cpu, ram, latency, bandwidth
app = Application(
application_id="my-app",
node_assets={"cpu": cpu, "ram": ram},
edge_assets={"latency": latency, "bandwidth": bandwidth},
)
# Add a service with specific resource requirements
app.add_node("service-A", cpu=1.0, ram=0.5)
app.add_node("service-B", cpu=2.0, ram=1.0, strict=False)
# Add a directional communication between services
app.add_edge(
"service-A", "service-B",
latency=5.0,
bandwidth=10.0,
symmetric=False
)
strict=True(default): raises an error if requirements are outside defined boundssymmetric=False(default): adds the edge in one direction only
If you’re building an application to run in emulation mode rather than simulation, each service must be implemented with actual logic and remote execution support.
See the Emulation guide for details.
Note
All assets passed to add_node() or add_edge() are checked against the declared asset definitions.
If validation fails and strict is True, an exception is raised. Otherwise, a warning is logged.
Default builders#
ECLYPSE provides several built-in builder functions that allow you to quickly
instantiate commonly used topologies and reference applications.
They return mutable Application or
Infrastructure objects with sensible
asset defaults and, for applications, representative flows.
from eclypse.builders.application import get_sock_shop
from eclypse.builders.infrastructure import get_fat_tree
infra = get_fat_tree(k=4, include_default_assets=True)
app = get_sock_shop(include_default_assets=True)
Tip
Builders are useful for prototyping or benchmarking standard scenarios. All returned graphs are mutable and can be extended using the standard interface. See Builders for the available builder families.