Skip to content

Commit 23d49d7

Browse files
committed
docs: add rust project (Marius)
1 parent 4d1bba5 commit 23d49d7

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Blueprint Architectural : Moteur de Rendu Réactif "Marius"
2+
3+
## 1. Philosophie & Paradigme (Le "Pourquoi")
4+
Ce système rejette l'approche classique (JIT, SPA, intermédiation par API JSON) au profit d'une architecture **Data-Oriented Design (DOD)** et **Ahead-Of-Time (AOT)**.
5+
6+
* **La donnée est le cache :** Le serveur n'est pas un médiateur interactif, c'est un moteur de projection. Il transforme un état SQL en un artéfact binaire (HTML).
7+
* **Déterminisme absolu :** Le temps de réponse en lecture doit être plat (soft real-time), sans Garbage Collection, limité uniquement par les I/O réseau.
8+
* **Zéro Indirection :** Suppression des couches de mapping (ORM) et de sérialisation. Les octets transitent de la base de données vers la mémoire contiguë (structs Rust) puis directement vers le buffer de sortie réseau.
9+
10+
## 2. La Stack Technique (Le "Quoi")
11+
Chaque outil est sélectionné pour son alignement avec la réduction de l'empreinte mémoire, le contrôle CPU et le typage fort.
12+
13+
* **Socle Système : Rust (LLVM)**. Garantit l'absence de Garbage Collector, la sécurité mémoire au moment de la compilation, et un footprint RAM minimal (~20 Mo).
14+
* **Runtime Asynchrone : Tokio**. Ordonnanceur multi-thread (Work-Stealing) pour maximiser l'usage CPU lors des I/O non-bloquants, sans l'overhead des threads OS bloquants.
15+
* **Réseau & Routing : Axum + Tower**. Serveur HTTP exploitant le typage statique de Rust pour l'extraction de données (zéro parsing manuel). Fournit les primitives système (compression Zstd/Gzip, streaming de fichiers).
16+
* **Moteur de Projection : Maud**. Macro Rust compilant les templates HTML directement en code machine. Zéro parsing au runtime.
17+
* **Protocole Client : HTMX**. Traite le navigateur comme un terminal d'affichage. Échange des fragments d'état (HTML) plutôt que des données (JSON), éliminant l'état applicatif côté client.
18+
* **Driver Data : SQLx**. Validation des requêtes SQL contre le schéma de la base de données *au moment de la compilation*. Mapping direct en structures mémoire.
19+
* **Source de Vérité : PostgreSQL**. Centralise les invariants métier. Pilote le système via des triggers et le protocole natif `LISTEN/NOTIFY`.
20+
* **Pipeline Assets : `build.rs` + `minify-js`**. Intégration AOT. Les assets (CSS/JS) sont minifiés, hashés et figés avant la compilation du binaire pour un cache navigateur immuable.
21+
22+
23+
24+
## 3. Topologie du Pipeline (Le "Comment")
25+
L'architecture sépare strictement le chemin de lecture (Read Path, critique en latence) du chemin d'écriture (Write Path, critique en débit).
26+
27+
### A. Le Chemin de Lecture (Read Path - O(1))
28+
1. **Requête HTTP** entrante gérée par Tokio/Axum.
29+
2. **Passthrough :** Axum sert l'artéfact projeté (fichier statique ou buffer RAM) via `sendfile(2)`.
30+
3. **Résultat :** Latence microseconde (~100µs), coût CPU quasi nul.
31+
32+
### B. Le Chemin de Mutation (Write Path & Projection Réactive)
33+
La résolution du problème d'amplification d'écriture (Write Amplification) est gérée par un pattern **Collector/Dispatcher**.
34+
35+
1. **Mutation :** Une transaction SQL est validée (ex: `CALL content.publish_document()`).
36+
2. **Signal :** PostgreSQL émet un événement `pg_notify` contenant l'ID de l'entité.
37+
3. **Collector (Dédoublonnement) :** Un worker Tokio intercepte le signal et place l'ID dans un `HashSet` en mémoire. Plusieurs mutations rapides sur le même ID sont écrasées (DOD).
38+
4. **Dispatcher (Batching) :** Selon un invariant temporel (ex: `tick` de 500ms) ou volumétrique (ex: `len() == 100`), le `HashSet` est vidé (`flush`).
39+
5. **Projection Parallèle :** Les $N$ entités uniques sont extraites via SQLx en lot, puis projetées simultanément en HTML via Maud sur tous les cœurs CPU (via Rayon/Tokio). L'artéfact cible est mis à jour.
40+
41+
## 4. Invariants Hybrides (Comportement Client)
42+
Bien que l'état global soit géré par le serveur, les micro-interactions locales (sans persistance requise) sont traitées en Just-In-Time (JIT) côté client.
43+
* **Règle :** Utilisation de Vanilla JS (ou outils légers) greffés sur des attributs natifs (ex: `aria-expanded`, `<details>`).
44+
* **Intégration HTMX :** Les scripts réactifs s'accrochent au hook `htmx.onLoad` pour garantir l'application du comportement aux fragments du DOM fraîchement injectés par le pipeline AOT.
45+
46+
***
47+
48+
Document rédigé le 25 mars 2026.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Le Manifeste de la Projection Réactive
2+
## Architecture Data-First & Rendu AOT
3+
4+
### 1. Vision Stratégique
5+
Le serveur web n'est plus un médiateur interactif, mais un **Système de Projection**. Il transforme de manière déterministe un flux de mutations de données (PostgreSQL) en artéfacts statiques ou semi-statiques (HTML via Maud), éliminant le besoin de caches intermédiaires (Redis, Memcached). L'artéfact généré *est* l'état optimal de lecture.
6+
7+
### 2. Résolution des Problèmes Classiques
8+
* **Invalidation du Cache :** Élimination de la logique temporelle (TTL). L'artéfact est réécrit uniquement lorsque la source de vérité le commande.
9+
* **Indirection de Transformation :** Suppression du mapping objet-relationnel (ORM) et de la sérialisation (JSON). Le pipeline transfère les octets directement du driver SQL aux buffers d'écriture HTML.
10+
* **Gaspillage CPU :** Le rendu est calculé une seule fois à l'écriture (AOT), libérant le CPU pour le transport réseau (I/O) lors de la lecture.
11+
12+
### 3. Invariants Structurels
13+
L'architecture repose sur trois piliers inaltérables :
14+
1. **Source de Vérité (PostgreSQL) :** Centralise la logique métier et l'état. Seule la base de données qualifie une mutation.
15+
2. **Canal de Transport (LISTEN/NOTIFY) :** Protocole asynchrone natif poussant les signaux de mutation vers le système applicatif.
16+
3. **Transformateur Pur (Rust + Maud) :** Un pipeline AOT (Ahead-of-Time) sans état interne, traduisant le modèle de données (`struct`) en mémoire contiguë (DOM/HTML).
17+
18+
### 4. Limite Physiologique : L'Amplification d'Écriture
19+
**Le Risque :** Dans un système réactif pur, une mise à jour massive en base de données (ex: 10 000 lignes modifiées via une procédure stockée) déclenche une avalanche de notifications. Traiter chaque signal individuellement sature le pipeline de rendu et les I/O disque/réseau, provoquant un goulot d'étranglement CPU.
20+
21+
### 5. La Solution DOD : Le Modèle Collector / Dispatch
22+
Pour protéger le transformateur, on interpose un système de regroupement (Batching) qui réduit l'entropie du flux d'événements.
23+
24+
* **Le Collector (Dédoublonnement en O(1)) :**
25+
Les signaux entrants sont stockés dans une structure contiguë avec contrainte d'unicité (un `HashSet` Rust). Si un même ID est modifié 50 fois dans un court intervalle, il n'est conservé qu'une fois dans le layout mémoire.
26+
* **Le Dispatcher (Tick & Seuil) :**
27+
Le vidage du Collector (`flush`) est régi par deux invariants stricts pour lisser la charge (Smoothing) :
28+
* *Volumétrique :* Déclenchement si la capacité maximale est atteinte (ex: 100 entités).
29+
* *Temporel :* Déclenchement périodique forcé (ex: toutes les 500ms).
30+
* **Parallélisme de Rendu :**
31+
Lors du `flush`, la liste dédoublonnée d'IDs est distribuée sur l'ensemble des cœurs CPU disponibles (via un ordonnanceur comme *Rayon* ou les workers *Tokio*). La projection de $N$ artéfacts s'exécute en simultané, garantissant une latence de mise à jour stable.
32+
33+
### 6. Pipeline Mécanique Global
34+
Le cycle de vie complet d'une donnée suit ce flux directionnel strict :
35+
36+
1. **Mutation DB :** `UPDATE content.document` $\rightarrow$ Trigger SQL.
37+
2. **Signal :** `pg_notify('updates', 'ID')`.
38+
3. **Capture :** Écouteur asynchrone Rust $\rightarrow$ Injection dans le `HashSet`.
39+
4. **Dispatch :** Seuil ou Tick atteint $\rightarrow$ Extraction des IDs uniques.
40+
5. **Extraction Data :** Requêtes `SELECT` par lots (Batch SQL).
41+
6. **Projection AOT :** Exécution des macros `Maud` (Multi-thread).
42+
7. **Persistance :** Remplacement atomique de l'artéfact (Fichier / RAM).
43+
44+
***
45+
46+
Document rédigé le 25 mars 2026.

0 commit comments

Comments
 (0)