Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .gitattributes

This file was deleted.

Empty file removed .github/workflows/ci-cd-main.yml
Empty file.
54 changes: 2 additions & 52 deletions .github/workflows/ci-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,33 +62,12 @@ jobs:


# Job 2 ─ Full validation (executed only on push events)
# --------------------------------------------------------------------------- #
# Includes everything from the quick job plus:
# • PostgreSQL service container
# • Alembic migrations
# • Integration tests
# • Multi-stage Docker build and health-check

full:
if: |
github.event_name == 'push' &&
github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest

services:
postgres:
image: postgres:17
env:
POSTGRES_USER: ${{ secrets.DB_USER }}
POSTGRES_PASSWORD: ${{ secrets.DB_PASSWORD }}
POSTGRES_DB: ${{ secrets.DB_NAME }}
ports: ["5432:5432"]
options: >-
--health-cmd "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB"
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
Expand All @@ -110,41 +89,12 @@ jobs:
- name: Run mypy
run: poetry run mypy src

- name: Apply Alembic migrations
env:
ENVIRONMENT: test
DB_URL: postgresql+psycopg://${{ secrets.DB_USER }}:${{ secrets.DB_PASSWORD }}@localhost:5432/${{ secrets.DB_NAME }}
run: poetry run alembic upgrade head

- name: Run all tests
env:
ENVIRONMENT: test
DB_URL: postgresql+asyncpg://${{ secrets.DB_USER }}:${{ secrets.DB_PASSWORD }}@localhost:5432/${{ secrets.DB_NAME }}
run: |
poetry run pytest \
--cov=src --cov-report=term \
--disable-warnings

- name: Build Docker image
run: docker build --progress=plain -t backend:ci .


- name: Smoke test container
run: |
# partiamo con --network host così il container condivide la rete del runner
docker run -d \
--name backend_ci \
--network host \
-e ENVIRONMENT=test \
-e DB_URL=postgresql+asyncpg://${{ secrets.DB_USER }}:${{ secrets.DB_PASSWORD }}@localhost:5432/${{ secrets.DB_NAME }} \
backend:ci \
uvicorn app.main:app --host 0.0.0.0 --port 8000

for i in {1..10}; do
if curl --silent --fail http://localhost:8000/health; then
echo "✔ Health OK"; break
else
echo "Waiting…"; sleep 3
fi
done

docker stop backend_ci

50 changes: 0 additions & 50 deletions Dockerfile

This file was deleted.

207 changes: 79 additions & 128 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,176 +1,127 @@
Certamente. Ecco il contenuto del `README.md` visualizzato direttamente qui.

-----

# **FastSim Project Overview**

## **1. Why FastSim?**

FastAPI + Uvicorn gives Python teams a lightning-fast async stack, yet sizing it for production still means guesswork, costly cloud load-tests, or late surprises. **FastSim** fills that gap by becoming a **digital twin** of your actual service:
Modern async Python stacks like FastAPI + Uvicorn are incredibly fast, yet sizing them for production often involves guesswork, costly cloud load-tests, or late-stage surprises. **FastSim** fills that gap by acting as a **digital twin** of your service:

* It **replicates** your FastAPI + Uvicorn event-loop behavior in SimPy, generating the same kinds of asynchronous steps (parsing, CPU work, I/O, LLM calls) that happen in real code.
* It **models** your infrastructure primitives—CPU cores (via a SimPy `Resource`), database pools, rate-limiters, and even GPU inference quotas—so you can see queue lengths, scheduling delays, resource utilization, and end-to-end latency.
* It **outputs** the very metrics you would scrape in production (p50/p95/p99 latency, ready-queue lag, concurrency, throughput, cost per LLM call), but entirely offline, in seconds.
* It **replicates** the behavior of an async event-loop in SimPy, generating the same kinds of steps (parsing, CPU work, I/O waits) that happen in real code.
* It **models** your infrastructure primitives—CPU cores, connection pools, and rate-limiters—so you can see queue lengths, scheduling delays, resource utilization, and end-to-end latency.
* It **outputs** the very metrics you would scrape in production (p50/p95/p99 latency, ready-queue lag, concurrency, throughput), but entirely offline, in seconds.

With FastSim you can ask, *“What happens if traffic doubles on Black Friday?”*, *“How many cores are needed to keep p95 latency below 100 ms?”*, or *“Is our LLM-driven endpoint ready for prime time?”*—and get quantitative answers **before** you deploy.
With FastSim, you can ask, *“What happens if traffic doubles on Black Friday?”*, *“How many cores are needed to keep p95 latency below 100 ms?”*, or *“Is our new endpoint ready for prime time?”*—and get quantitative answers **before** you deploy.

**Outcome:** Data-driven capacity planning, early performance tuning, and far fewer surprises in production.

## **2. Project Goals**

| \# | Goal | Practical Outcome |
| :--- | :--- | :--- |
| 1 | **Pre-production sizing** | Know the required core count, pool size, and replica count to meet your SLA. |
| 2 | **Scenario analysis** | Explore various traffic models, endpoint mixes, latency distributions, and RTT. |
| 3 | **Twin metrics** | Produce the same metrics you’ll scrape in production (latency, queue length, CPU utilization). |
| 4 | **Rapid iteration** | A single YAML/JSON configuration or REST call generates a full performance report. |
| 5 | **Educational value** | Visualize how GIL contention, queue length, and concurrency react to load. |

## **3. Who Benefits & Why**

| Audience | Pain-Point Solved | FastSim Value |
| :--- | :--- | :--- |
| **Backend Engineers** | Unsure if a 4-vCPU container can survive a marketing traffic spike. | Run *what-if* scenarios, tweak CPU cores or pool sizes, and get p95 latency and max-concurrency metrics before merging code. |
| **DevOps / SRE** | Guesswork in capacity planning; high cost of over-provisioning. | Simulate 1 to N replicas, autoscaler thresholds, and database pool sizes to find the most cost-effective configuration that meets the SLA. |
| **ML / LLM Product Teams** | LLM inference cost and latency are difficult to predict. | Model the LLM step with a price and latency distribution to estimate cost-per-request and the benefits of GPU batching without needing real GPUs. |
| **Educators / Trainers** | Students struggle to visualize event-loop internals. | Visualize GIL ready-queue lag, CPU vs. I/O steps, and the effect of blocking code—perfect for live demos and labs. |
| **Consultants / Architects** | Need a quick proof-of-concept for new client designs. | Define endpoints in YAML and demonstrate throughput and latency under projected load in minutes. |
| **Open-Source Community** | Lacks a lightweight Python simulator for ASGI workloads. | An extensible codebase makes it easy to plug in new resources (e.g., rate-limiters, caches) or traffic models (e.g., spike, uniform ramp). |
| **System-Design Interviewees** | Hard to quantify trade-offs in whiteboard interviews. | Prototype real-time metrics—queue lengths, concurrency, latency distributions—to demonstrate how your design scales and where bottlenecks lie. |

## **4. About This Documentation**
## **2. Installation & Quick Start**

This project contains extensive documentation covering its vision, architecture, and technical implementation. The documents are designed to be read in sequence to build a comprehensive understanding of the project.
FastSim is designed to be used as a Python library.

### **How to Read This Documentation**
```bash
# Installation (coming soon to PyPI)
pip install fastsim
```

For the best understanding of FastSim, we recommend reading the documentation in the following order:
**Example Usage:**

1. Define your system topology in a `config.yml` file:

```yaml
topology:
servers:
- id: "app-server-1"
# ... server configuration ...
load_balancers:
- id: "main-lb"
backends: ["app-server-1"]
# ... lb configuration ...
settings:
duration_s: 60
```

1. **README.md (This Document)**: Start here for a high-level overview of the project's purpose, goals, target audience, and development workflow. It provides the essential context for all other documents.
2. **dev_worflow_guide**: This document details the github workflow for the development
3. **simulation_input**: This document details the technical contract for configuring a simulation. It explains the `SimulationPayload` and its components (`rqs_input`, `topology_graph`, `sim_settings`). This is essential reading for anyone who will be creating or modifying simulation configurations.
4. **runtime_and_resources**: A deep dive into the simulation's internal engine. It explains how the validated input is transformed into live SimPy processes (Actors, Resources, State). This is intended for advanced users or contributors who want to understand *how* the simulation works under the hood.
5. **requests_generator**: This document covers the mathematical and algorithmic details behind the traffic generation model. It is for those interested in the statistical foundations of the simulator.
6. **Simulation Metrics**: A comprehensive guide to all output metrics. It explains what each metric measures, how it's collected, and why it's important for performance analysis.
2. Run the simulation from a Python script:

Optional **fastsim_vision**: a more detailed document about the project vision
```python
from fastsim import run_simulation
from fastsim.schemas import SimulationPayload

you can find the documentation at the root of the project in the folder `documentation/`
# Load and validate configuration using Pydantic
payload = SimulationPayload.from_yaml("config.yml")

## **5. Development Workflow & Architecture Guide**
# Run the simulation
results = run_simulation(payload)

This section outlines the standardized development workflow, repository architecture, and branching strategy for the FastSim backend.
# Analyze and plot results
results.plot_latency_distribution()
print(results.summary())
```

### **Technology Stack**
## **3. Who Benefits & Why**

* **Backend**: FastAPI
* **Backend Package Manager**: Poetry
* **Frontend**: React + JavaScript
* **Database**: PostgreSQL
* **Caching**: Redis
* **Containerization**: Docker
| Audience | Pain-Point Solved | FastSim Value |
| :--- | :--- | :--- |
| **Backend Engineers** | Unsure if a 4-vCPU container can survive a traffic spike. | Run *what-if* scenarios, tweak CPU cores, and get p95 latency metrics before merging code. |
| **DevOps / SRE** | Guesswork in capacity planning; high cost of over-provisioning. | Simulate 1 to N replicas to find the most cost-effective configuration that meets the SLA. |
| **ML / LLM Teams** | LLM inference cost and latency are difficult to predict. | Model the LLM step with a price and latency distribution to estimate cost-per-request. |
| **Educators / Trainers** | Students struggle to visualize event-loop internals. | Visualize GIL ready-queue lag, CPU vs. I/O steps, and the effect of blocking code. |
| **System-Design Interviewees** | Hard to quantify trade-offs in whiteboard interviews. | Prototype real-time metrics to demonstrate how your design scales and where bottlenecks lie. |

### **Backend Service (`FastSim-backend`)**
## **4. Project Structure**

The repository hosts the entire FastAPI backend, which exposes the REST API, runs the discrete-event simulation, communicates with the database, and provides metrics.
The project is a standard Python library managed with Poetry.

```
fastsim-backend/
├── Dockerfile
├── docker_fs/
│ ├── docker-compose.dev.yml
│ └── docker-compose.prod.yml
├── scripts/
│ ├── init-docker-dev.sh
│ └── quality-check.sh
├── alembic/
│ ├── env.py
│ └── versions/
fastsim/
├── documentation/
│ └── backend_documentation/
├── tests/
│ ├── unit/
│ └── integration/
│ └── ...
├── src/
│ └── app/
│ ├── api/
│ ├── config/
│ ├── db/
│ ├── metrics/
│ ├── resources/
│ ├── runtime/
│ │ ├── rqs_state.py
│ │ └── actors/
│ │ ├── actors/
│ │ └── rqs_state.py
│ ├── samplers/
│ ├── schemas/
│ ├── main.py
│ └── simulation_run.py
├── poetry.lock
│ └── schemas/
├── tests/
│ ├── unit/
│ └── integration/
├── .github/
│ └── workflows/
│ └── ci-develop.yml
├── pyproject.toml
├── poetry.lock
└── README.md
```

### **How to Start the Backend with Docker (Development)**
## **5. Development & Contribution**

To spin up the backend and its supporting services in development mode:

1. **Install & run Docker** on your machine.
2. **Clone** the repository and `cd` into its root.
3. Execute:
```bash
bash ./scripts/init-docker-dev.sh
```
This will launch a **PostgreSQL** container and a **Backend** container that mounts your local `src/` folder with live-reload enabled.

### **Development Architecture & Philosophy**

We split responsibilities between Docker-managed services and local workflows.

* **Docker-Compose for Development**: Containers host external services (PostgreSQL) and run the FastAPI app. Your local `src/` directory is mounted into the backend container for hot-reloading. No tests, migrations, or linting run inside these containers during development.
* **Local Quality & Testing Workflow**: All code quality tools, migrations, and tests are executed on your host machine for faster feedback and full IDE support.
We welcome contributions\! The development workflow is managed by Poetry and quality is enforced by Ruff and MyPy.

| Task | Command | Notes |
| :--- | :--- | :--- |
| **Lint & format** | `poetry run ruff check src tests` | Style and best-practice validations |
| **Type checking** | `poetry run mypy src tests` | Static type enforcement |
| **Unit tests** | `poetry run pytest -m "not integration"` | Fast, isolated tests—no DB required |
| **Integration tests** | `poetry run pytest -m integration` | Real-DB tests against Docker’s PostgreSQL |
| **DB migrations** | `poetry run alembic upgrade head` | Applies migrations to your local Docker-hosted DB |

**Rationale**: Running tests or Alembic migrations inside Docker images would slow down your feedback loop and limit IDE features by requiring you to mount the full source tree and install dev dependencies in each build.

## **6. CI/CD with GitHub Actions**
| **Install dependencies** | `poetry install --with dev` | Installs main and development packages. |
| **Lint & format** | `poetry run ruff check src tests` | Style and best-practice validations. |
| **Type checking** | `poetry run mypy src tests` | Static type enforcement. |
| **Run all tests** | `poetry run pytest` | Executes the full test suite. |

We maintain two jobs on the `develop` branch to ensure code quality and stability.
### **CI with GitHub Actions**

### **Quick (on Pull Requests)**
We maintain two jobs on the `develop` branch to ensure code quality:

* Ruff & MyPy checks
* Unit tests only
* **No database required**
* **Quick (on Pull Requests):** Runs Ruff, MyPy, and unit tests for immediate feedback.
* **Full (on pushes to `develop`):** Runs the full suite, including integration tests and code coverage reports.

### **Full (on pushes to `develop`)**
This guarantees that every commit in `develop` is style-checked, type-safe, and fully tested.

* All checks from the "Quick" suite
* Starts a **PostgreSQL** service container
* Runs **Alembic** migrations
* Executes the **full test suite** (unit + integration)
* Builds the **Docker** image
* **Smoke-tests** the `/health` endpoint of the built container
## **6. Limitations – v0.1 (First Public Release)**

**Guarantee**: Every commit in `develop` is style-checked, type-safe, database-tested, and Docker-ready.
1. **Network Delay Model:** Only pure transport latency is simulated. Bandwidth-related effects (e.g., payload size, link speed) are not yet accounted for.
2. **Concurrency Model:** The simulation models a single-threaded, cooperative event-loop (like `asyncio`). Multi-process or multi-threaded parallelism is not yet supported.
3. **CPU Core Allocation:** Every server instance is pinned to one physical CPU core. Horizontal scaling is achieved by adding more server instances, not by using multiple cores within a single process.

## **7. Limitations – v0.1 (First Public Release)**
These constraints will be revisited in future milestones.

1. **Network Delay Model**
* Only pure transport latency is simulated.
* Bandwidth-related effects (e.g., payload size, link speed, congestion) are NOT accounted for.
2. **Concurrency Model**
* The service exposes **async-only endpoints**.
* Execution runs on a single `asyncio` event-loop thread.
* No thread-pool workers or multi-process setups are supported yet; therefore, concurrency is limited to coroutine scheduling (cooperative, single-thread).
3. **CPU Core Allocation**
* Every server instance is pinned to **one physical CPU core**.
* Horizontal scaling must be achieved via multiple containers/VMs, not via multi-core utilization inside a single process.
## **7. Documentation**

These constraints will be revisited in future milestones once kernel-level context-switching costs, I/O bandwidth modeling, and multi-process orchestration are integrated.
For a deeper understanding of FastSim, we recommend reading the detailed documentation located in the `/documentation` folder at the root of the project. A guided reading path is suggested within to build a comprehensive understanding of the project's vision, architecture, and technical implementation.
Loading