# lauraindabur/auto-scaling-controller architecture

> Architecture diagram of the GitHub repository lauraindabur/auto-scaling-controller, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/lauraindabur/auto-scaling-controller
- Repository: https://github.com/lauraindabur/auto-scaling-controller

## Overview

This repository is an AWS horizontal auto-scaling controller. Its principal workflow polls for completed CloudWatch periods, validates metric freshness and completeness, derives reactive CPU and proactive demand signals, combines them under safety guards, then adjusts ASG desired capacity and records the cycle. Startup restores policy and guard state from a local JSON file. The repository also documents a Flask workload target and a k6 scenario-based load experiment. Some implementation headers were not sampled, so links among policy internals and unsampled integrations are omitted rather than inferred.

Main entry points: [`include/DecisionEngine.hpp`](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/DecisionEngine.hpp) (Decision Engine), [`src/main.cpp`](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/main.cpp) (Controller Loop), [`src/CloudWatchMetricSource.cpp`](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/CloudWatchMetricSource.cpp) (CloudWatch Metric Source), [`src/StateStore.cpp`](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/StateStore.cpp) (State Store)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_controller["Controller Runtime"]
  node_main["Controller Loop<br/>[main.cpp]"]
  node_engine["Decision Engine<br/>[DecisionEngine.hpp]"]
  node_config["Environment Config<br/>[Config.hpp]"]
  node_logger["Decision Logger<br/>[Logger.cpp]"]
  node_logfile["Decision Log"]
  node_state["State Store<br/>[StateStore.cpp]"]
  node_statefile["Persisted State"]
end

subgraph group_decision["Decision Logic"]
  node_quality["Metric Quality<br/>[DataQuality.hpp]"]
  node_reactive["Reactive Policy<br/>[ReactivePolicy.hpp]"]
  node_moving["Moving Average<br/>[MovingAverage.hpp]"]
  node_proactive["Proactive Policy"]
  node_holt["Holt Forecast<br/>[HoltForecaster.hpp]"]
  node_combiner["Decision Combiner"]
  node_guards["Safety Guards<br/>[SafetyGuards.hpp]"]
end

subgraph group_aws["AWS Integrations"]
  node_metrics["CloudWatch Metric Source"]
  node_actuator["ASG Actuator<br/>[ASGActuator.cpp]"]
end

subgraph group_workload["Workload Experiment"]
  node_loadtest["k6 Load Scenario"]
  node_scenario["Scenario Profile"]
  node_app["Flask Workload App<br/>[app.py]"]
end

node_operator(("Operator"))
node_cloudwatch["CloudWatch"]
node_asg["Auto Scaling Group"]
node_alb["Application Load Balancer"]

node_operator -->|"starts"| node_main
node_main -->|"loads settings"| node_config
node_main -->|"loads state"| node_state
node_state -->|"reads / writes"| node_statefile
node_main -->|"runs loop"| node_engine
node_main -->|"restores policy"| node_reactive
node_main -->|"restores policy"| node_proactive
node_main -->|"restores forecast"| node_holt
node_engine -->|"requests snapshot"| node_metrics
node_metrics -->|"queries metrics"| node_cloudwatch
node_metrics -->|"describes group"| node_asg
node_engine -->|"evaluates snapshot"| node_quality
node_engine -->|"updates signal"| node_reactive
node_reactive -->|"maintains window"| node_moving
node_engine -->|"updates signal"| node_proactive
node_engine -->|"combines signals"| node_combiner
node_combiner -->|"checks actions"| node_guards
node_engine -->|"requests capacity"| node_actuator
node_actuator -->|"sets desired capacity"| node_asg
node_engine -->|"records decision"| node_logger
node_logger -->|"writes entries"| node_logfile
node_engine -->|"persists controller state"| node_state
node_loadtest -->|"reads phases"| node_scenario
node_loadtest -->|"sends HTTP load"| node_alb
node_alb -->|"routes requests"| node_app

click node_main "https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/main.cpp"
click node_engine "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/DecisionEngine.hpp"
click node_config "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/Config.hpp"
click node_quality "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/DataQuality.hpp"
click node_reactive "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/ReactivePolicy.hpp"
click node_moving "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/MovingAverage.hpp"
click node_proactive "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/ProactivePolicy.hpp"
click node_holt "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/HoltForecaster.hpp"
click node_combiner "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/DecisionCombiner.hpp"
click node_guards "https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/SafetyGuards.hpp"
click node_metrics "https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/CloudWatchMetricSource.cpp"
click node_actuator "https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/ASGActuator.cpp"
click node_logger "https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/Logger.cpp"
click node_state "https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/StateStore.cpp"
click node_loadtest "https://github.com/lauraindabur/auto-scaling-controller/blob/main/loadtest/k6/escenario_completo.js"
click node_scenario "https://github.com/lauraindabur/auto-scaling-controller/blob/main/loadtest/scenarios/escenario_completo.csv"
click node_app "https://github.com/lauraindabur/auto-scaling-controller/blob/main/infra/app/app.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_engine,node_config,node_logger,node_logfile,node_state,node_statefile toneBlue
class node_quality,node_reactive,node_moving,node_proactive,node_holt,node_combiner,node_guards toneAmber
class node_metrics,node_actuator toneMint
class node_loadtest,node_scenario,node_app toneRose
class node_operator,node_cloudwatch,node_asg,node_alb toneIndigo
```

## Components

### Controller Runtime

- [Controller Loop](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/main.cpp): `src/main.cpp`
- [Decision Engine](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/DecisionEngine.hpp): `include/DecisionEngine.hpp`
- [Environment Config](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/Config.hpp): `include/Config.hpp`
- [Decision Logger](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/Logger.cpp): `src/Logger.cpp`
- **Decision Log**
- [State Store](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/StateStore.cpp): `src/StateStore.cpp`
- **Persisted State**

### Decision Logic

- [Metric Quality](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/DataQuality.hpp): `include/DataQuality.hpp`
- [Reactive Policy](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/ReactivePolicy.hpp): `include/ReactivePolicy.hpp`
- [Moving Average](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/MovingAverage.hpp): `include/MovingAverage.hpp`
- [Proactive Policy](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/ProactivePolicy.hpp): `include/ProactivePolicy.hpp`
- [Holt Forecast](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/HoltForecaster.hpp): `include/HoltForecaster.hpp`
- [Decision Combiner](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/DecisionCombiner.hpp): `include/DecisionCombiner.hpp`
- [Safety Guards](https://github.com/lauraindabur/auto-scaling-controller/blob/main/include/SafetyGuards.hpp): `include/SafetyGuards.hpp`

### AWS Integrations

- [CloudWatch Metric Source](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/CloudWatchMetricSource.cpp): `src/CloudWatchMetricSource.cpp`
- [ASG Actuator](https://github.com/lauraindabur/auto-scaling-controller/blob/main/src/ASGActuator.cpp): `src/ASGActuator.cpp`

### Workload Experiment

- [k6 Load Scenario](https://github.com/lauraindabur/auto-scaling-controller/blob/main/loadtest/k6/escenario_completo.js): `loadtest/k6/escenario_completo.js`
- [Scenario Profile](https://github.com/lauraindabur/auto-scaling-controller/blob/main/loadtest/scenarios/escenario_completo.csv): `loadtest/scenarios/escenario_completo.csv`
- [Flask Workload App](https://github.com/lauraindabur/auto-scaling-controller/blob/main/infra/app/app.py): `infra/app/app.py`

### Other components

- **Operator**
- **CloudWatch**
- **Auto Scaling Group**
- **Application Load Balancer**

## Connections

- Operator → Controller Loop: starts
- Controller Loop → Environment Config: loads settings
- Controller Loop → State Store: loads state
- State Store → Persisted State: reads / writes
- Controller Loop → Decision Engine: runs loop
- Controller Loop → Reactive Policy: restores policy
- Controller Loop → Proactive Policy: restores policy
- Controller Loop → Holt Forecast: restores forecast
- Decision Engine → CloudWatch Metric Source: requests snapshot
- CloudWatch Metric Source → CloudWatch: queries metrics
- CloudWatch Metric Source → Auto Scaling Group: describes group
- Decision Engine → Metric Quality: evaluates snapshot
- Decision Engine → Reactive Policy: updates signal
- Reactive Policy → Moving Average: maintains window
- Decision Engine → Proactive Policy: updates signal
- Decision Engine → Decision Combiner: combines signals
- Decision Combiner → Safety Guards: checks actions
- Decision Engine → ASG Actuator: requests capacity
- ASG Actuator → Auto Scaling Group: sets desired capacity
- Decision Engine → Decision Logger: records decision
- Decision Logger → Decision Log: writes entries
- Decision Engine → State Store: persists controller state
- k6 Load Scenario → Scenario Profile: reads phases
- k6 Load Scenario → Application Load Balancer: sends HTTP load
- Application Load Balancer → Flask Workload App: routes requests
