doctrine(bdd-testing): remplacer le caveat poll par la règle « ne jamais poller »
L'ancien caveat_poll-broker-reads érigeait à tort le POLLING en pratique de test. Remarque utilisateur : le polling est un anti-pattern dans le contexte NextGraph (par abonnement). Remplacé par rule_no-broker-polling : attendre le push réactif / la barrière du 1er State ; ne JAMAIS re-interroger le broker en boucle. Fallback pragmatique admis : un intervalle court qui OBSERVE l'état réactif déjà mis à jour (pas une re-lecture broker) — au plus près de l'utilisateur qui attend. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
---
|
||||
type: caveat
|
||||
summary: Les lectures @data/@multibrowser contre le broker réel convergent avec un lag de sync (~s) — asserter en POLLING borné, jamais en lecture unique ; une lecture one-shot course la fenêtre de sync/réactivité et flake. Vaut pour les lectures à froid (reconnexion) ET la propagation réactive (compteur cross-navigateur).
|
||||
last_checked: 2026-07-08
|
||||
---
|
||||
|
||||
# Asserter les lectures broker en polling, pas en one-shot
|
||||
|
||||
Contre le **broker réel** (@data, @multibrowser), une donnée écrite n'est pas
|
||||
lisible **instantanément** par un lecteur : il y a un **lag de sync** (le CRDT du
|
||||
doc doit se propager/s'ouvrir avant qu'une lecture ancrée le rende). Mesuré : une
|
||||
donnée fraîche se lit typiquement en **~1 s**, parfois après la 1ʳᵉ tentative.
|
||||
|
||||
**Piège** : une assertion qui lit **une seule fois**, tout de suite, **course
|
||||
cette fenêtre** et échoue de façon **flaky** — alors que le comportement applicatif
|
||||
est correct (l'UI réelle est **réactive** : `doc_subscribe` fait converger l'écran
|
||||
en quelques secondes). Un test qui lit one-shot mesure le lag, pas le bug.
|
||||
|
||||
**Règle** : asserter en **POLLING borné** (re-lire en boucle jusqu'à ~10-15 s max)
|
||||
la condition attendue. C'est ce que fait déjà la matérialisation côté steps ; toute
|
||||
NOUVELLE assertion de lecture doit suivre le même pattern.
|
||||
|
||||
Deux familles concernées, toutes deux vérifiées :
|
||||
- **Lecture à froid / reconnexion** — une session verifier fraîche (page fraîche,
|
||||
nouveau login) relit ses propres docs après ouverture de repo ; la 1ʳᵉ lecture
|
||||
peut rendre 0, la suivante les données. Voir `event/reconnexion-meme-identite`
|
||||
(les 3 `Then` de la page fraîche pollent) et `event/steps/data/reconnexion.steps.ts`.
|
||||
- **Propagation réactive cross-navigateur** — un compteur écrit par le propriétaire
|
||||
se propage au `doc_subscribe` d'un autre navigateur ; asserter « passe à {int}
|
||||
sans reload » en attendant la convergence. Voir le scénario réactif de
|
||||
`event/e2e-multibrowser.feature` (POV A **et** B).
|
||||
|
||||
Ce caveat porte sur **comment écrire les assertions** contre le broker — pas sur
|
||||
les internes NextGraph (lag/sync/ouverture de repo), qui vivent dans le repo
|
||||
`@ng-eventually/client`. Voir aussi [[caveat_wallet-bloat-hang]] (autre source de
|
||||
flakiness @data : le profil gonflé qui fait hanger les requêtes ancrées).
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
type: rule
|
||||
summary: Ne JAMAIS poller le broker (re-lire en boucle « c'est là ? »). NextGraph est par abonnement — la donnée arrive par PUSH, et le 1er `State` d'un `doc_subscribe` est la barrière de sync déterministe (après lui : présence garantie / absence définitive). Tests ET app attendent le push / l'état réactif settlé, jamais une boucle de re-lecture broker.
|
||||
last_checked: 2026-07-09
|
||||
---
|
||||
|
||||
# Ne jamais poller le broker — attendre l'abonnement
|
||||
|
||||
NextGraph est **par abonnement (réactif)**. Une lecture n'est PAS « interroge en
|
||||
boucle jusqu'à ce que ça apparaisse » ; c'est « abonne-toi, réagis au push ». Le
|
||||
**1er `State`** d'un `doc_subscribe` marque la fin de la synchronisation initiale
|
||||
(barrière synchrone) : après lui, la **présence** d'une donnée est **garantie** et
|
||||
l'**absence** est **définitive**. Contrat vérifié empiriquement côté SDK
|
||||
(`@ng-eventually/client`, test e2e « CONTRAT 3 »).
|
||||
|
||||
## L'anti-pattern à bannir
|
||||
|
||||
```
|
||||
for (i = 0; i < N; i++) { if (await authParticipationCount(...) === X) break; sleep(500); }
|
||||
```
|
||||
|
||||
Toute boucle qui **re-interroge le broker** (`authParticipationCount`,
|
||||
`listMyEntityDocs`, `sparql_query` répétés) pour « attendre » une donnée est
|
||||
proscrite : elle masque le vrai mécanisme, fragilise le test (timeout deviné), et
|
||||
contredit frontalement le modèle NextGraph. C'est la remarque qui a fait supprimer
|
||||
l'ancien caveat qui, à tort, érigeait le polling en pratique.
|
||||
|
||||
## Ce qu'il faut faire
|
||||
|
||||
Attendre le **push réactif**. En pratique (app ET test) : l'état réactif
|
||||
(`AD().*` alimenté par `subscribeDoc` dans le contexte de données) se met à jour
|
||||
**au push**. On attend que CET état reflète l'attendu — on **observe l'état réactif
|
||||
settlé**, on ne ré-émet PAS de lecture broker. Le mécanisme de données est
|
||||
l'abonnement ; l'attente ne fait qu'**observer le résultat réactif**.
|
||||
|
||||
- App : l'écran est déjà réactif (`subscribeDoc` → re-render au push) — pas de poll
|
||||
applicatif, pas de spinner piloté par timeout deviné (si un état d'attente est
|
||||
voulu, il vient de la barrière d'abonnement native, pas d'un signal ajouté).
|
||||
- Test : **un helper qui attend le push/la barrière de façon fiable est bienvenu**
|
||||
(fiabilise sans fragiliser). Ce qui est banni, c'est la **boucle de re-lecture**,
|
||||
pas l'attente d'un signal.
|
||||
- **Fallback pragmatique** : si attendre strictement le push/signal s'avère fragile
|
||||
d'une manière ou d'une autre, un **intervalle court** (`setInterval` / re-check
|
||||
rapproché) qui **observe l'état réactif DÉJÀ mis à jour** (l'état local alimenté
|
||||
par l'abonnement — PAS une re-lecture broker) est acceptable : c'est au plus près
|
||||
de ce que vit l'utilisateur, qui **attend** simplement que l'écran (réactif) se
|
||||
mette à jour. La ligne rouge est invariante : **ne jamais re-interroger le broker
|
||||
en boucle** ; observer l'état réactif settlé, oui.
|
||||
|
||||
Voir aussi [[caveat_wallet-bloat-hang]] (autre source de flakiness @data,
|
||||
orthogonale). Le mécanisme non-polling côté lib (`open-repo` : subscribe + attendre
|
||||
le 1er State + lire) vit dans le repo `@ng-eventually/client`, pas ici.
|
||||
Reference in New Issue
Block a user