docs: document Lardon3D architecture foundations
This commit is contained in:
parent
d5b6216ef8
commit
6379dce843
2 changed files with 233 additions and 0 deletions
121
docs/architecture/foundation_review.md
Normal file
121
docs/architecture/foundation_review.md
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
# Revue technique des fondations
|
||||||
|
|
||||||
|
## Périmètre et conclusion
|
||||||
|
|
||||||
|
Cette revue couvre `task`, `task_queue`, le profil matériel, les snapshots de
|
||||||
|
ressources, le gouverneur, les réservations et leur intégration au scheduler.
|
||||||
|
Aucune fuite, course, interblocage ou violation reproductible de l'invariant
|
||||||
|
d'admission n'a été détecté par l'inspection et les tests actuels. Aucun code de
|
||||||
|
production n'a donc été modifié.
|
||||||
|
|
||||||
|
## Invariants actuellement garantis
|
||||||
|
|
||||||
|
- Une tâche possède une estimation copiée à sa création et exposée seulement
|
||||||
|
par copie.
|
||||||
|
- Le scheduler reçoit explicitement son gouverneur et refuse un gouverneur nul.
|
||||||
|
- Le worker obtient une réservation active avant d'appeler
|
||||||
|
`lardon3d_task_start`; celui-ci revalide la réservation avant le callback.
|
||||||
|
- Un callback lancé par la file dispose d'une copie cohérente de son contrat :
|
||||||
|
lot, RAM, GPU, CPU et slots IO/GPU.
|
||||||
|
- `WAIT` conserve la tâche en tête et endort le worker sur une condition
|
||||||
|
variable. Le mutex de file empêche une notification concurrente de se perdre
|
||||||
|
entre la décision et l'attente.
|
||||||
|
- `REJECT` termine la tâche sans appeler son callback. `REDUCE_BATCH` transmet
|
||||||
|
le contrat réduit.
|
||||||
|
- La réservation détenue par le worker est libérée après succès, échec ou
|
||||||
|
annulation. Une pause en cours conserve volontairement la réservation.
|
||||||
|
- La destruction de la file annule les tâches, réveille et rejoint le worker,
|
||||||
|
puis détruit les tâches dont elle est propriétaire.
|
||||||
|
- Les compteurs du gouverneur et la création des réservations sont protégés par
|
||||||
|
un mutex unique. Une double libération est refusée sans débiter les budgets.
|
||||||
|
- Les calculs de taille contrôlent multiplication et addition ; les compteurs
|
||||||
|
CPU et slots ne peuvent croître au-delà des budgets calculés.
|
||||||
|
- Le profil représente les capacités stables. Les snapshots sont des valeurs
|
||||||
|
datées et indépendantes ; le scheduler ne prend aucune décision de ressources
|
||||||
|
lui-même.
|
||||||
|
|
||||||
|
## Limites connues
|
||||||
|
|
||||||
|
- La file possède un seul worker et applique un FIFO strict. Une tâche en tête
|
||||||
|
qui reçoit `WAIT` bloque les tâches suivantes, même si certaines seraient
|
||||||
|
admissibles.
|
||||||
|
- Une libération extérieure au scheduler exige ensuite un appel à
|
||||||
|
`lardon3d_task_queue_resources_changed`. Le gouverneur ne publie pas encore
|
||||||
|
automatiquement cet événement.
|
||||||
|
- Les réservations libérées restent comme tombstones jusqu'à la destruction du
|
||||||
|
gouverneur. Cela sécurise la double libération mais fait croître la mémoire
|
||||||
|
avec le nombre historique de contrats.
|
||||||
|
- Une erreur de capture du snapshot fait échouer la tâche ; il n'existe pas
|
||||||
|
encore de distinction entre erreur transitoire de mesure et rejet durable.
|
||||||
|
- Le gouverneur et la file doivent être détruits après arrêt de leurs appelants.
|
||||||
|
Leur destruction concurrente avec une API active n'est pas prise en charge.
|
||||||
|
- Les tâches, checkpoints, files et réservations ne sont pas persistés.
|
||||||
|
- Il n'existe ni DAG, ni priorité, ni pool de workers, ni orchestration de
|
||||||
|
séquences adaptatives successives.
|
||||||
|
|
||||||
|
## Risques à surveiller
|
||||||
|
|
||||||
|
- Formaliser l'ordre de durée de vie : la file doit être détruite avant son
|
||||||
|
gouverneur ; une tâche cédée à la file ne doit plus être détruite directement.
|
||||||
|
- Ne jamais permettre à un composant extérieur de libérer la réservation privée
|
||||||
|
du worker. L'appel `get_active` et le démarrage sont sûrs dans le modèle de
|
||||||
|
propriété actuel, pas face à une libération concurrente volontaire.
|
||||||
|
- Éviter qu'un callback détruise ou joigne sa propre tâche, ce qui pourrait
|
||||||
|
attendre sa propre fin.
|
||||||
|
- Conserver les prédicats autour de chaque attente de condition et maintenir le
|
||||||
|
même mutex pour décision `WAIT` et mise en sommeil.
|
||||||
|
- Surveiller les identifiants et compteurs historiques sur les très longues
|
||||||
|
sessions, même si leur débordement est irréaliste avec les allocations
|
||||||
|
actuelles.
|
||||||
|
- Ne pas transformer `MemAvailable`, le swap ou la zram en promesse de mémoire
|
||||||
|
supplémentaire. Les snapshots peuvent déjà refléter une consommation réelle
|
||||||
|
en plus des réservations comptables ; une politique future doit rester
|
||||||
|
conservatrice.
|
||||||
|
- Garder la publication de résultats indépendante du contrat d'exécution : seul
|
||||||
|
un résultat validé atomiquement peut devenir visible.
|
||||||
|
|
||||||
|
## Cohérence documentaire
|
||||||
|
|
||||||
|
Les documents actuels correspondent au code : responsabilités séparées,
|
||||||
|
réservation préalable, pause conservant les ressources, worker unique et
|
||||||
|
notification explicite. La vue d'ensemble décrit comme futurs — et non comme
|
||||||
|
existants — les séquences complètes, la reprise persistante, les snapshots live
|
||||||
|
et le viewer Vulkan.
|
||||||
|
|
||||||
|
## Ordre recommandé des prochains tickets
|
||||||
|
|
||||||
|
1. Formaliser les contrats de propriété, les événements de libération et les
|
||||||
|
erreurs transitoires de snapshot.
|
||||||
|
2. Définir un format de résultat atomique avec identifiant, validation et point
|
||||||
|
de reprise.
|
||||||
|
3. Ajouter l'enchaînement borné de lots adaptatifs sous réservations successives.
|
||||||
|
4. Borner les files et introduire la contre-pression.
|
||||||
|
5. Persister tâches et checkpoints nécessaires à la reprise après crash.
|
||||||
|
6. Ajouter ensuite un DAG minimal, puis les priorités.
|
||||||
|
7. Généraliser vers des pools CPU, IO et GPU en conservant le gouverneur comme
|
||||||
|
unique arbitre.
|
||||||
|
8. Publier des snapshots validés avant d'introduire le viewer séparé.
|
||||||
|
|
||||||
|
## Éléments à ne pas réécrire lors du passage à OpenCode
|
||||||
|
|
||||||
|
- Les structures opaques `Task`, `TaskQueue`, `ResourceGovernor` et
|
||||||
|
`ResourceReservation`.
|
||||||
|
- La séparation profil matériel / snapshot dynamique / politique / réservation.
|
||||||
|
- Le calcul centralisé et protégé des budgets et lots.
|
||||||
|
- L'invariant « réservation active avant callback » et la copie du contrat vers
|
||||||
|
la tâche.
|
||||||
|
- L'annulation coopérative, les checkpoints de pause et la propriété ncurses du
|
||||||
|
thread principal.
|
||||||
|
- Le FIFO à condition variable comme implémentation V1 fiable ; il doit évoluer
|
||||||
|
par extension, pas être remplacé avant que les besoins DAG soient spécifiés.
|
||||||
|
- Les écritures atomiques, rollbacks ciblés et validations déjà utilisés par les
|
||||||
|
projets et imports.
|
||||||
|
- Les tests de concurrence, de double libération, d'annulation et de destruction
|
||||||
|
sûre, qui constituent la base de non-régression.
|
||||||
|
|
||||||
|
## Validation exécutée
|
||||||
|
|
||||||
|
- Suite normale : 10 tests réussis sur 10.
|
||||||
|
- ASan/UBSan : 10 tests réussis sur 10, aucun diagnostic.
|
||||||
|
- TSan : 10 tests réussis sur 10, aucune course signalée.
|
||||||
|
- `git diff --check` : réussi avant la rédaction du présent rapport.
|
||||||
112
docs/architecture/overview.md
Normal file
112
docs/architecture/overview.md
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
# Vue d'ensemble de l'architecture Lardon3D
|
||||||
|
|
||||||
|
## Finalité et flux global
|
||||||
|
|
||||||
|
Lardon3D est une application Linux de reconstruction 3D pilotée par une TUI
|
||||||
|
ncursesw. Le terminal reste le centre de contrôle : il gère les projets, lance
|
||||||
|
les opérations, présente leur progression et permet leur annulation. Le futur
|
||||||
|
viewer Vulkan sera un processus ou composant graphique séparé, affiché sur le
|
||||||
|
workspace 8 ; il ne remplacera pas la TUI et ne devra jamais la bloquer.
|
||||||
|
|
||||||
|
```text
|
||||||
|
TUI / Projet
|
||||||
|
↓
|
||||||
|
Task
|
||||||
|
↓
|
||||||
|
Estimate
|
||||||
|
↓
|
||||||
|
Governor
|
||||||
|
↓
|
||||||
|
Reservation
|
||||||
|
↓
|
||||||
|
Scheduler
|
||||||
|
↓
|
||||||
|
Worker
|
||||||
|
↓
|
||||||
|
Résultat atomique
|
||||||
|
↓
|
||||||
|
Viewer live
|
||||||
|
```
|
||||||
|
|
||||||
|
## Composants actuels
|
||||||
|
|
||||||
|
Les projets persistants regroupent leur configuration, les images originales,
|
||||||
|
le manifeste, les résultats de reconstruction, les exports et les journaux.
|
||||||
|
Leur création est protégée contre l'écrasement et les écritures structurantes
|
||||||
|
utilisent des remplacements atomiques.
|
||||||
|
|
||||||
|
L'import d'images s'exécute de manière asynchrone et annulable, sans appel
|
||||||
|
ncurses depuis son worker. Il copie individuellement les fichiers admissibles
|
||||||
|
et maintient un manifeste cohérent. Le catalogue charge et valide ce manifeste
|
||||||
|
en mémoire. La vue d'images en dérive des indices triés et filtrés sans modifier
|
||||||
|
le catalogue, le manifeste ou les images.
|
||||||
|
|
||||||
|
Le moteur de tâches fournit les états, la progression, la pause, l'annulation
|
||||||
|
coopérative et les callbacks. La file actuelle possède un worker unique et
|
||||||
|
respecte l'ordre FIFO. Chaque tâche porte une estimation immuable de ses coûts
|
||||||
|
RAM, GPU, CPU et IO ainsi que des bornes de lot.
|
||||||
|
|
||||||
|
Le profil matériel décrit les capacités stables détectées sur la machine. Les
|
||||||
|
snapshots décrivent les ressources disponibles à un instant donné. Le Resource
|
||||||
|
Governor combine profil, snapshot, marges de sécurité et réservations actives.
|
||||||
|
Il décide si une demande doit démarrer, attendre, réduire son lot ou être
|
||||||
|
refusée, puis matérialise toute admission par une réservation opaque.
|
||||||
|
|
||||||
|
Le scheduler ne décide jamais des ressources. Il demande une réservation au
|
||||||
|
gouverneur juste avant l'exécution et transmet au callback une copie du contrat
|
||||||
|
accordé. L'invariant est strict : aucun callback de tâche n'est lancé sans
|
||||||
|
réservation active validée. Après succès, échec ou annulation, cette réservation
|
||||||
|
est libérée exactement une fois. Une tâche déjà en pause conserve son contrat
|
||||||
|
dans cette première version.
|
||||||
|
|
||||||
|
## Résultats et publication live
|
||||||
|
|
||||||
|
Les traitements futurs fonctionneront par séquences adaptatives : lire un lot
|
||||||
|
borné, calculer, écrire un résultat atomique, libérer la mémoire, puis traiter
|
||||||
|
le lot suivant. La stabilité du système hôte et la réactivité de la TUI ont
|
||||||
|
priorité sur le débit maximal.
|
||||||
|
|
||||||
|
Le viewer live ne devra observer que des snapshots de résultats complètement
|
||||||
|
validés et publiés atomiquement. Il ne lira jamais un fichier intermédiaire et
|
||||||
|
ne partagera pas directement les buffers de travail d'un worker. Une
|
||||||
|
interruption doit laisser le dernier snapshot validé exploitable et permettre
|
||||||
|
la reprise à une frontière de séquence connue.
|
||||||
|
|
||||||
|
## Principes non négociables
|
||||||
|
|
||||||
|
- Aucune tâche lourde monolithique ni chargement complet d'un projet en RAM.
|
||||||
|
- Traitement par séquences adaptatives et libération entre les lots.
|
||||||
|
- Budgets RAM, GPU, CPU et IO explicitement bornés et réservés.
|
||||||
|
- Files de travail et buffers intermédiaires bornés.
|
||||||
|
- La zram est un filet de sécurité, jamais une extension du budget normal.
|
||||||
|
- La RAM partagée des iGPU est comptabilisée dans le budget système.
|
||||||
|
- Écritures atomiques, rollback ciblé et absence de résultat partiellement
|
||||||
|
publié.
|
||||||
|
- Reprise après interruption depuis le dernier état validé.
|
||||||
|
- Viewer live séparé, non bloquant et lecteur de snapshots validés seulement.
|
||||||
|
- Le système hôte, la TUI et les données utilisateur restent prioritaires sur
|
||||||
|
le débit de reconstruction.
|
||||||
|
|
||||||
|
## Limites actuelles
|
||||||
|
|
||||||
|
La file ne possède encore ni DAG, ni priorités, ni pool de workers CPU/IO/GPU.
|
||||||
|
Les tâches et leur progression ne sont pas persistées après un arrêt. Les
|
||||||
|
séquences adaptatives sont préparées par les contrats de lot mais leur
|
||||||
|
enchaînement complet n'est pas encore orchestré. Le viewer Vulkan et la
|
||||||
|
publication live restent à implémenter.
|
||||||
|
|
||||||
|
## Ordre recommandé des prochains tickets
|
||||||
|
|
||||||
|
1. Définir les résultats atomiques, leurs métadonnées de validation et leurs
|
||||||
|
points de reprise.
|
||||||
|
2. Introduire l'exécution d'une tâche en séquences de lots adaptatifs, toujours
|
||||||
|
sous réservations successives.
|
||||||
|
3. Borner explicitement les files et définir la contre-pression entre étapes.
|
||||||
|
4. Persister les tâches, checkpoints et états nécessaires à la reprise après
|
||||||
|
crash.
|
||||||
|
5. Ajouter un DAG minimal et seulement ensuite les priorités.
|
||||||
|
6. Introduire des pools CPU, IO et GPU sans déplacer l'arbitrage hors du
|
||||||
|
gouverneur.
|
||||||
|
7. Publier des snapshots live validés et versionnés.
|
||||||
|
8. Ajouter le viewer Vulkan séparé sur le workspace 8 comme consommateur en
|
||||||
|
lecture seule de ces snapshots.
|
||||||
Loading…
Reference in a new issue