Nodefony
Framework Node.js fullstack — HTTP & WebSocket, même contexte

Campagne de test — Nodefony 10.0.0

Aucune régression du produit. Tous les rouges sont instruits et imputés au décor ou à l'instrument.

Le verdict

Cas passés
11 701
passage le plus large (étage A)
Régressions du produit
0
aucune
Rouges de décor ou d'instrument
16
n'appartiennent pas au code
Cas non exécutés
249
sur ce même passage
Les étages se recouvrent — C1 rejoue le socle avec des interrupteurs ouverts. Ces chiffres sont donc ceux du passage le plus large, jamais une somme : additionner compterait trois fois la même suite. Et un total ne dit rien seul — 249 cas n'ont pas tourné sur ce seul passage, un cas sauté comptant comme vert. Ce que la campagne n'a pas éprouvé est en bas de page, au même rang que le reste.

Ce qui a été joué, étage par étage

A — Non-régression + dialectes
npm run test:all -- --dialects
L unique rouge est un flake de saturation : 15/15 en 2,4 s isolé.11 70112499,8 min● vert
B — Charge + mémoire
npm run test:all -- --load
Gate mémoire 9/9, marges ×10 à ∞.10 147—1773,4 min● vert
C1 — Interrupteurs perf / boots CLI / cluster
NF_RUN_PERF=1 NF_RUN_CLI_BOOT=1 NF_RUN_CLUSTER_E2E=1 npm run test:all
114 tests de plus exercés. Les 9 rouges sont tous du décor, verts en isolé.10 21796113,8 min● instruit
C2 — Sondes de rupture WebSocket
run.sh load --rupture
Plafond 8 000 sockets ; 100 000 frames sans perte.7—222,1 min● vert
C3 — Coupures RÉELLES de base
NF_RUN_DB_OUTAGE=1 + conteneurs nommés
PostgreSQL, MariaDB, MongoDB arrêtés et relancés ; bascule de primaire comprise.15——1,8 min● vert
D — Bancs e2e et de mesure
par lots (catalogue nodefony-load-test)
20 bancs e2e + 13 bancs de mesure, après correction de 4 décors mal classés.33——~25 min● vert
E — Ce que le scaffold produit
verify-generated.mjs --keep puis verify-runtime.mjs
Vérité et conformité (3 étages) vertes. Le contrôle de FORMAT est cassé et orphelin → #215.21—~12 min● instruit
F — Multi-pods
setup.sh puis run.sh + matrice d attaque
Attaque du bus 5/5 et 4 mesures vertes. Les 3 bancs de pod face à leur base exigent une base adoptée → #216.93—~15 min● instruit
G — Chaîne de publication
npm run release:pack puis release:smoke
15 tarballs ; 3 scénarios (base, front, studio) prouvés depuis une image vierge.3——~8 min● vert

Les rouges, triés par cause instruite

Sur une campagne complète, le produit est le dernier suspect. Chaque rouge est instruit avant d'être imputé : le même cas passe-t-il isolé (saturation) ? le décor est-il celui que le banc suppose ? un état partagé s'est-il accumulé ? l'instrument dit-il vrai ?
● saturation7@nodefony/realtime — clusterIpc.e2e ×5, redisCluster.e2e ×2worker fork: ready timeout (5 s / 6 s)5/5 puis 2/2 verts en isolé ; fan-out Redis mesuré p50 53 ms / p99 60 ms.
● saturation1@nodefony/drizzle — migrate-adopttimeout 20 s puis ENOTEMPTY au retryvert isolé en 1 054 ms.
● état partagé1@nodefony/http — session-revocationgarde-fou de pagination : expected 60 to be below 605 816 sessions résiduelles dans Redis ; après purge, 7/7 en 571 ms contre 48 539 ms.
● instrument1racine — format:scaffoldnpm error 404 sur @nodefony/devkitgénère sans installer depuis les tarballs ; branché dans aucun workflow. → #215
● décor3multi-pods — db-outage / db-readiness / db-persistanceNF_MIGRATE_BASELINE_REQUIREDexigent une base adoptée, que rien ne documente. → #216
● instrument3bancs de charge — scaffold-ws-probe, app-download-probe, poc-hmr-perfmethod not found: scaffold:run ; ws errordeux bancs périmés, un défaut d URL en clair face à un Vite en TLS. → #217

Seuils mémoire

1 000 GET séquentiels-0,4435∞
100 crashs synchrones0,0910×111,1
100 crashs asynchrones0,0710×142,9
100 TypeError natifs0,1015×150,0
500 requêtes mixtes1,8820×10,6
200 envois multipart0,9230×32,6
100 connexions WS0,0030∞
50 allers-retours WS0,0225×1 250,0

Capacité d'un pod

http/1.1 (clair)2 409±19 %0,6299 %
https/1.1 (TLS)2 911±3 %2,4693 %
h2 (multiplexé)3 229±3 %0,7590 %
Plafond WebSocket
8 000 sockets
13.33 KB par connexion
Écho WebSocket
10 303 msg/s
1 pour 1
Diffusion
381 578 liv./s
1 vers 100 sockets
Latence cross-pod
3 ms (p50)
50 000 livraisons, 0 % de perte
Décor : Hyperviseur actif pendant la campagne (Docker Desktop, 8 vCPU réservés sur 12) — les ABSOLUS ne sont pas transposables, les comparaisons intra-fenêtre le sont. Ces chiffres situent un ordre de grandeur ; ils ne se transposent pas à une autre machine.

Tenue dans la durée — la pente que le nombre cache

Trois runs, trois décors. Le tas V8 reste plat et les handles ne bougent pas : ce n'est pas une fuite d'objets. Le RSS monte, mais ce compteur est trompeur sous macOS — il inclut les pages que l'allocateur a déjà rendues au noyau. Mesurée à part, l'empreinte système reste plate (164 → 164 MB sur 29 fenêtres), et leaks ne trouve que 3 Ko sur 20,7 millions de requêtes.
mémoire résidente `rss` (MB) selon fenêtrerun1 — RSS : 1 → 246, 2 → 253, 3 → 255, 4 → 259, 5 → 265, 6 → 266, 7 → 269, 8 → 271, 9 → 273, 10 → 274, 11 → 276, 12 → 275 · run2 — RSS : 1 → 245, 2 → 250, 3 → 251, 4 → 252, 5 → 254, 6 → 257, 7 → 262, 8 → 263, 9 → 266, 10 → 267, 11 → 269, 12 → 274, 13 → 278, 14 → 277, 15 → 277, 16 → 279, 17 → 280, 18 → 284, 19 → 285, 20 → 289, 21 → 291, 22 → 295, 23 → 296, 24 → 298, 25 → 298, 26 → 300, 27 → 303, 28 → 303, 29 → 306, 30 → 308, 31 → 310, 32 → 315, 33 → 315, 34 → 315, 35 → 320, 36 → 323, 37 → 324, 38 → 330, 39 → 334, 40 → 334, 41 → 336, 42 → 336, 43 → 340, 44 → 342, 45 → 344 · run3 — RSS : 1 → 245, 2 → 253, 3 → 255, 4 → 260, 5 → 268, 6 → 272, 7 → 275, 8 → 273, 9 → 280, 10 → 282, 11 → 285, 12 → 291, 13 → 294, 14 → 299, 15 → 300, 16 → 304, 17 → 311, 18 → 313, 19 → 320, 20 → 325, 21 → 330, 22 → 334, 23 → 340, 24 → 341, 25 → 345, 26 → 350, 27 → 351, 28 → 354, 29 → 358, 30 → 359, 31 → 360, 32 → 366, 33 → 368, 34 → 371, 35 → 210 0 185 371 1 12 23 34 45 fenêtre mémoire résidente `rss` (MB)tas V8 (MB) selon fenêtrerun1 — tas V8 : 1 → 43, 2 → 44, 3 → 44, 4 → 44, 5 → 44, 6 → 44, 7 → 44, 8 → 44, 9 → 44, 10 → 44, 11 → 44, 12 → 44 · run2 — tas V8 : 1 → 43, 2 → 44, 3 → 44, 4 → 44, 5 → 44, 6 → 44, 7 → 44, 8 → 44, 9 → 44, 10 → 44, 11 → 44, 12 → 44, 13 → 44, 14 → 44, 15 → 44, 16 → 44, 17 → 44, 18 → 44, 19 → 44, 20 → 44, 21 → 44, 22 → 44, 23 → 44, 24 → 44, 25 → 44, 26 → 44, 27 → 44, 28 → 44, 29 → 44, 30 → 44, 31 → 44, 32 → 44, 33 → 44, 34 → 44, 35 → 44, 36 → 44, 37 → 44, 38 → 44, 39 → 44, 40 → 44, 41 → 44, 42 → 44, 43 → 44, 44 → 44, 45 → 44 · run3 — tas V8 : 1 → 43, 2 → 44, 3 → 44, 4 → 44, 5 → 44, 6 → 44, 7 → 44, 8 → 44, 9 → 44, 10 → 44, 11 → 44, 12 → 44, 13 → 44, 14 → 44, 15 → 44, 16 → 44, 17 → 44, 18 → 44, 19 → 44, 20 → 44, 21 → 44, 22 → 44, 23 → 44, 24 → 44, 25 → 44, 26 → 44, 27 → 44, 28 → 44, 29 → 44, 30 → 44, 31 → 44, 32 → 44, 33 → 44, 34 → 44, 35 → 44 0 22 44 1 12 23 34 45 fenêtre tas V8 (MB)
RunDurée retenueDécorTasHandlesVerdict du banc
run113 min retenuesmachine chargéeplat (+0,4 MB)stablesINDÉTERMINÉ (< 10 min) — et empreinte système non mesurée
run284 min retenuesdécor NON tenu (charge montée à 10,89)plat (+0,5 MB)stableshausse du `rss` seul — NON CONCLUSIF : l'empreinte système n'a pas été relevée
run3~68 min utilesmachine libreplat (44,2 MB constant)stables`rss` 255 → 371 MB ; serveur arrêté à la fenêtre 35 (échéance de dérogation) — NON CONCLUSIF, et le « plateau » annoncé est un artefact
Deux réserves, et la seconde annule la conclusion que ces courbes semblaient porter. (1) La chute finale du troisième run n'est PAS une mesure : le serveur s'est arrêté à l'échéance de sa dérogation aux modules de développement, et le banc a moyenné cette mort dans sa régression — d'où un « plateau » qui n'existe pas. (2) Ces trois runs n'ont relevé que rss. Sous macOS, ce compteur inclut les pages que l'allocateur a déjà rendues au noyau ; mesuré depuis sur le même décor, il s'agit de 93 % de la hausse. L'empreinte réelle du processus, elle, ne bouge pas. Ces courbes montrent donc un compteur qui monte, pas une mémoire qui se consomme.

Ce que cette campagne n'a PAS éprouvé

Un banc sauté compte comme vert. Cette liste est la moitié du verdict.
  • Le front d une application générée (le banc de vérité ne monte pas Vite).
  • Les dialectes PostgreSQL et MySQL du code généré (seul sqlite a été joué).
  • Le comparatif de frameworks et l A/B de production mono — écartés pour ne pas fausser les mesures en cours.
  • La tenue au-delà de 90 minutes : aucun run ne prouve trois jours.
  • Les bancs de découvrabilité et de schéma du devkit (agents réels, coût dédié).

Ce que la campagne a ouvert

TicketObjetJalonPriorité
#215réparer le contrôle de format du code généré10.0.0P1
#216poser la base que trois bancs multi-pods exigentbacklogP3
#217réparer trois bancs de charge hors servicebacklogP3
#218caractériser la hausse du RSS d un pod sous chargebacklogP2