Skip to content

Commit c9ca0d3

Browse files
committed
feat: update images and screenshots
1 parent b71e830 commit c9ca0d3

32 files changed

+365
-484
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ make up # Start services
2626
- **Dashboard:** http://localhost:3000 (Grafana)
2727
- **API:** http://localhost:3001 (OpenAPI docs)
2828

29+
![OpenDT Grafana Dashboard](site/src/components/HomepageFeatures/grafana-dashboard.png)
30+
*Real-time dashboard comparing actual vs. simulated power consumption*
31+
2932
---
3033

3134
## Repository Structure

config/default.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ services:
1111

1212
simulator:
1313
simulation_frequency_minutes: 5
14+
background_load_nodes: 0
1415

1516
kafka:
1617
topics:

config/experiments/experiment_1.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ services:
1111

1212
simulator:
1313
simulation_frequency_minutes: 60
14+
background_load_nodes: 0
1415

1516
kafka:
1617
topics:

config/experiments/experiment_2.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ services:
1111

1212
simulator:
1313
simulation_frequency_minutes: 60
14+
background_load_nodes: 0
1415

1516
calibrator:
1617
calibrated_property: "cpuPowerModel.calibrationFactor"

libs/common/odt_common/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ class SimulatorConfig(BaseModel):
6666
simulation_frequency_minutes: int = Field(
6767
default=15, description="Simulation frequency in minutes (simulated time)", gt=0
6868
)
69+
background_load_nodes: int = Field(
70+
...,
71+
description="Number of nodes reserved for background load (not available for simulation)",
72+
ge=0,
73+
)
6974

7075

7176
class CalibratorConfig(BaseModel):
47.6 KB
Binary file not shown.

services/simulator/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,18 @@ Settings under `services.simulator` in the config file:
7979
| Setting | Type | Default | Description |
8080
|---------|------|---------|-------------|
8181
| simulation_frequency_minutes | int | 5 | Window size for task aggregation |
82+
| background_load_nodes | int | (required) | Number of nodes reserved for background load |
8283

8384
### simulation_frequency_minutes
8485

8586
Determines the time window size for batching tasks. Larger windows mean fewer OpenDC invocations but less granular results.
8687

88+
### background_load_nodes
89+
90+
Simulates a certain number of nodes being used for background load. These nodes are subtracted from the first host type in the first cluster of the topology and are not available for assigning workload in the simulation.
91+
92+
This is useful when the real datacenter has nodes running workloads that are not part of the simulated task trace (e.g., system services, other tenants). Set to `0` to use the full topology.
93+
8794
## Logs
8895

8996
```

services/simulator/simulator/main.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def __init__(
4242
speed_factor: float,
4343
run_output_dir: str,
4444
run_id: str,
45+
background_load_nodes: int = 0,
4546
consumer_group: str = "simulators",
4647
):
4748
"""Initialize the simulation service.
@@ -55,6 +56,7 @@ def __init__(
5556
speed_factor: Configured simulation speed multiplier
5657
run_output_dir: Base directory for run outputs
5758
run_id: Unique run ID for this session
59+
background_load_nodes: Number of nodes reserved for background load
5860
consumer_group: Kafka consumer group ID
5961
"""
6062
self.kafka_bootstrap_servers = kafka_bootstrap_servers
@@ -65,6 +67,7 @@ def __init__(
6567
self.simulation_frequency = timedelta(minutes=simulation_frequency_minutes)
6668
self.speed_factor = speed_factor
6769
self.run_id = run_id
70+
self.background_load_nodes = background_load_nodes
6871

6972
# Setup output directories - simulator writes to run_dir/simulator/
7073
self.output_base_dir = Path(run_output_dir) / run_id / "simulator"
@@ -121,6 +124,50 @@ def __init__(
121124
logger.info(
122125
f"Simulation frequency: {simulation_frequency_minutes} minutes (simulated time)"
123126
)
127+
logger.info(f"Background load nodes: {background_load_nodes}")
128+
129+
def _reduce_topology_for_background_load(self, topology: Topology) -> Topology:
130+
"""Create a topology with reduced host count to simulate background load.
131+
132+
Subtracts background_load_nodes from the first host type in the first cluster.
133+
This simulates nodes being occupied by background workload and unavailable
134+
for the simulation.
135+
136+
Args:
137+
topology: Original topology
138+
139+
Returns:
140+
New topology with reduced host count in first cluster
141+
"""
142+
if self.background_load_nodes == 0:
143+
return topology
144+
145+
# Deep copy to avoid modifying the original
146+
reduced = copy.deepcopy(topology)
147+
148+
if not reduced.clusters or not reduced.clusters[0].hosts:
149+
logger.warning("Topology has no clusters or hosts, cannot reduce")
150+
return topology
151+
152+
first_host = reduced.clusters[0].hosts[0]
153+
original_count = first_host.count
154+
155+
if self.background_load_nodes >= original_count:
156+
logger.warning(
157+
f"background_load_nodes ({self.background_load_nodes}) >= "
158+
f"available hosts ({original_count}) in first cluster, "
159+
f"setting to {original_count - 1}"
160+
)
161+
first_host.count = max(1, original_count - self.background_load_nodes)
162+
else:
163+
first_host.count = original_count - self.background_load_nodes
164+
165+
logger.info(
166+
f"Reduced topology: {original_count} -> {first_host.count} hosts "
167+
f"in cluster '{reduced.clusters[0].name}' ({self.background_load_nodes} for background load)"
168+
)
169+
170+
return reduced
124171

125172
def _run_simulation(self) -> None:
126173
"""Run OpenDC simulation with accumulated tasks.
@@ -235,8 +282,8 @@ def _run_simulation(self) -> None:
235282
# Increment run number
236283
self.run_number += 1
237284

238-
# Check if we can reuse cached results
239-
topology_to_use = self.simulated_topology
285+
# Apply background load reduction to topology
286+
topology_to_use = self._reduce_topology_for_background_load(self.simulated_topology)
240287

241288
# Create directories
242289
run_dir = self.output_base_dir / "opendc" / f"run_{self.run_number}"
@@ -462,6 +509,7 @@ def main():
462509

463510
# Get simulator configuration
464511
simulation_frequency_minutes = config.services.simulator.simulation_frequency_minutes
512+
background_load_nodes = config.services.simulator.background_load_nodes
465513
speed_factor = config.global_config.speed_factor
466514
run_output_dir = Path(os.getenv("DATA_DIR", "/app/data"))
467515

@@ -470,6 +518,7 @@ def main():
470518
logger.info(f"Topology topic: {topology_topic}")
471519
logger.info(f"Simulated topology topic: {sim_topology_topic}")
472520
logger.info(f"Simulation frequency: {simulation_frequency_minutes} minutes")
521+
logger.info(f"Background load nodes: {background_load_nodes}")
473522
logger.info(f"Speed factor: {speed_factor}x")
474523
logger.info(f"Data directory: {run_output_dir}")
475524

@@ -500,6 +549,7 @@ def main():
500549
speed_factor=speed_factor,
501550
run_output_dir=str(run_output_dir),
502551
run_id=run_id,
552+
background_load_nodes=background_load_nodes,
503553
consumer_group=consumer_group,
504554
)
505555
service.run()

site/community/0-support.mdx

Lines changed: 0 additions & 39 deletions
This file was deleted.

site/community/1-team.mdx

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)