feat: complete initial project structure for API and Monitoring Dashboards

هذا الالتزام موجود في:
mac
2026-07-27 13:44:44 +03:00
التزام 4fd4bb72e1
21 ملفات معدلة مع 821 إضافات و0 حذوفات

عرض الملف

@@ -0,0 +1,22 @@
# Using ghaymah Block Storage for Stateful Workloads
Containers are inherently stateless; they lose their local filesystem data when they are destroyed or rescheduled. For applications that require persistent data (Stateful Workloads), we utilize **ghaymah Block Storage**.
## 1. What is Block Storage?
Block Storage provides persistent, highly available disk volumes that can be attached to containers. Unlike object storage (S3), it behaves like a physical hard drive mounted to the OS.
## 2. Use Cases in our Architecture
While our API application is mostly stateless, certain workloads require persistence:
- **Local Caching:** If a container downloads large datasets or machine learning models upon startup, these can be stored on Block Storage so subsequent container restarts are faster.
- **Session Data / Logs:** If we are writing complex audit logs that haven't yet been shipped to a centralized logging service.
- **Databases:** If running a self-managed database (e.g., PostgreSQL or Redis) within a container, Block Storage is mandatory to prevent data loss.
## 3. Configuration & Mounting
When deploying via the `ghaymah deploy` CLI or dashboard, we specify a volume mount:
```yaml
volumes:
- name: my-persistent-data
size: 50GB
mountPath: /mnt/data
```
Inside the container, the application can simply read/write files to `/mnt/data/` knowing the data will survive container restarts.

24
architecture/capacity.md Normal file
عرض الملف

@@ -0,0 +1,24 @@
# Capacity Planning: Handling 15,000 req/s
To ensure high availability and responsiveness under a load of 15,000 requests per second, we must calculate the required number of container instances.
## Base Assumptions
- **Target Load:** 15,000 req/s
- **Max Capacity per Container:** 500 req/s
- **Safety Margin:** 30%
## Calculation
1. **Effective Capacity per Container:**
To maintain a 30% margin, we calculate the effective capacity each container should handle before we consider scaling out.
`500 req/s * (1 - 0.30) = 350 req/s`
2. **Total Containers Required:**
Divide the total expected load by the effective capacity per container.
`15,000 req/s / 350 req/s per container ≈ 42.85`
3. **Rounding Up:**
We cannot have a fraction of a container, so we always round up to the next whole number.
`ceil(42.85) = 43 containers`
## Conclusion
To safely handle 15,000 req/s while maintaining a 30% safety margin (which helps absorb sudden traffic spikes or the failure of a few containers), the auto-scaling group should be configured to maintain a baseline of **43 containers** during peak load.

عرض الملف

@@ -0,0 +1,20 @@
# Cold Start Strategy
When auto-scaling responds to a traffic spike, new containers must be initialized. The time it takes from the scaling decision to the container actually serving requests is the "cold start" latency.
To minimize this delay and prevent dropped requests, we implement the following strategy:
## 1. Lightweight Base Images
- Use Alpine or distroless base images (e.g., `python:3.11-alpine`).
- Smaller images pull faster from the Container Registry over the network.
## 2. Pre-warming (Buffer Pool)
- Configure the Auto-Scaling Group to always maintain a "buffer" of idle containers (e.g., 10% of the current required capacity).
- If we need 43 containers for active load, we run ~47 containers. When traffic spikes, these 4 idle containers can serve requests instantly while the ASG provisions new ones.
## 3. Lazy Loading & Readiness Probes
- Defer non-critical initialization (like building large in-memory caches) until *after* the container has started accepting requests.
- Configure Kubernetes/ghaymah readiness probes to accurately reflect when the app is ready to serve traffic, ensuring the load balancer doesn't route traffic to a container that is still booting.
## 4. Keep-Alive & Connection Pooling
- Ensure idle containers aren't prematurely terminated. Keep database connections alive in a connection pool to avoid the latency of establishing new TCP handshakes during a sudden burst.

26
architecture/diagram.mmd Normal file
عرض الملف

@@ -0,0 +1,26 @@
```mermaid
graph TD
Client((Client Requests <br> 15,000 req/s)) --> WAF[Web Application Firewall]
WAF --> LB[ghaymah Load Balancer]
subgraph Auto-Scaling Group
direction LR
LB -->|Traffic Distribution| API1[myapp-api Container 1 <br> ~350 req/s]
LB --> API2[myapp-api Container 2 <br> ~350 req/s]
LB --> API3[myapp-api Container 3]
LB -.-> APIN[myapp-api Container N <br> Total: 43 Containers]
end
API1 --> BS1[(ghaymah Block Storage <br> /mnt/data)]
API2 --> BS2[(ghaymah Block Storage <br> /mnt/data)]
API3 --> BS3[(ghaymah Block Storage <br> /mnt/data)]
APIN --> BSN[(ghaymah Block Storage <br> /mnt/data)]
classDef container fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
classDef lb fill:#fff3e0,stroke:#e65100,stroke-width:2px;
classDef storage fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
class API1,API2,API3,APIN container;
class LB lb;
class BS1,BS2,BS3,BSN storage;
```