Documentation · Le moteur

Un flush valide l'état. Un snapshot le matérialise.

Generic System sépare trois choses que l'on confond trop vite : la mutation dans le cache, le commit transactionnel, et la persistance sur disque. Le moteur les traite comme des frontières distinctes.

Le chemin d'une mutation

De l'appel Java à l'état vivant.

Une mutation ne va jamais directement du code au disque. Elle traverse des étapes qui chacune peuvent être observées, validées ou abandonnées.

ÉtapeCe qui se passe
Cache courantLe changement est porté par un différentiel (adds / removes) ; il est déjà visible dans ce contexte.
flush()Les contraintes sont validées, puis le différentiel est appliqué à l'état vivant de l'Engine.
TransactionLe commit applique atomiquement suppressions et ajouts, sous contrôle MVCC.
Caches réactifsLe delta du commit (removedTs / addedTs) est publié ; les vues se mettent à jour sans tout reconstruire.
ArchiverPériodiquement, ou à l'arrêt propre, l'état est matérialisé dans un snapshot disque.

Le temps dans le modèle

Un cycle de vie par nœud.

Chaque Generic porte birthTs, lastReadTs et deathTs. Il est vivant pour un contexte ts si birthTs ≤ ts < deathTs. La suppression ferme le cycle sans réécrire l'identité du nœud.

Concurrence

Deux familles de conflit.

Un conflit rejouable (ConcurrencyControlException) conduit flush() à décaler son timestamp et à réessayer. Un conflit d'état (OptimisticLockConstraintViolationException) n'est pas rejouable : il invalide le différentiel.

Durabilité

Le graphe est matérialisé sur disque.

Un flush() applique le changement dans l'état vivant de l'Engine. Les snapshots périodiques matérialisent ensuite le graphe sur disque ; un arrêt propre écrit un dernier snapshot.

Lorsqu'une opération exige une matérialisation immédiate, engine.forceSnapshot() la déclenche explicitement. Le choix du moment de persistance reste ainsi visible et maîtrisable par l'application.

Le moteur fournit un modèle transactionnel cohérent et une persistance explicite du graphe. Les choix d'architecture d'exploitation sont documentés avec l'environnement qui les met en œuvre.

Le verrou .lock

Ne jamais le supprimer pour « débloquer ».

Une base persistante est protégée par un FileLock exclusif. Le fichier .lock n'est que le support visible du verrou : le supprimer pendant que le processus vit peut laisser deux processus écrire la même base, sans aucune erreur. La règle est d'identifier et d'arrêter proprement le détenteur.

Local ou distant

Le même graphe, deux accès.

En local, Engine exécute directement. À distance, ClientEngine présente le graphe hébergé comme un Root identique : la différence se situe sous le cache. Voir l'hébergement GSDS →

Démontré

Le kernel est couvert par sa propre suite de tests.

Le module gs-kernel porte environ 1 000 tests (146 fichiers), qui servent aussi de documentation exécutable : cache, concurrence, persistance, visibilité réactive, intégrité de suppression.

La migration à froid des schémas @SystemGeneric est couverte par des tests dédiés (commit 6b1aa6ac5, 2026-07-16). La validation du moteur se fait avec ./build-gs.sh --clean gs-kernel puis mvn clean test depuis le module.

Continuer

Le même graphe, déclaré en Java.

Jusqu'ici le modèle est construit dynamiquement. On peut aussi le déclarer une fois avec des annotations @SystemGeneric : la page suivante montre le même domaine, versionné avec le code.