0.3.4-alpha.4

This commit is contained in:
2026-09-21 18:00:32 +02:00
parent bbecae5e0d
commit fa17ea0ca5
12 changed files with 792 additions and 47 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Plan 0.3.4 — transport realtime et baseline WebSocket
@@ -7,7 +7,7 @@
Plan actif créé pendant `0.3.4-alpha.1` à partir de l'archive taggée `v0.3.3`.
Les tranches `alpha.1` et `alpha.2` ont été validées le 2026-09-21. La validation de `alpha.3` a révélé un défaut de manifeste Cargo avant compilation : une crate membre ne peut pas remplacer `default-features` d'une dépendance héritée du workspace. La tranche active `alpha.3.fix.1` corrige uniquement cet héritage ; les limites, timeouts et cas négatifs complets restent réservés à `alpha.4`.
Les tranches `alpha.1`, `alpha.2` et `alpha.3.fix.1` ont été validées le 2026-09-21. `alpha.3` avait été rejetée avant compilation à cause d'un héritage Cargo invalide de `default-features`; son fix a ensuite validé le backend WebSocket, le round-trip localhost et le graphe sans TLS. La tranche active `alpha.4` ferme maintenant les limites, timeouts, cas négatifs et lifecycle avant consolidation/beta.
## Mission
@@ -82,7 +82,7 @@ Contraintes utiles :
- `native-tls` et les variantes `rustls-*` sont optionnelles ;
- Tungstenite expose déjà des limites de message/frame et de write buffer configurables.
`alpha.3.fix.1` centralise désormais aussi `default-features = false` sous `[workspace.dependencies]`, car Cargo interdit à une dépendance membre héritée de remplacer cette option. `game-realtime-websocket-lib` ajoute seulement les features locales `sink + std` pour `futures-util` et `connect + handshake` pour `tokio-tungstenite`; aucune feature TLS n'est activée. La compatibilité effective de la toolchain utilisateur sera attestée par la gate Cargo utilisateur du fix.
`alpha.3.fix.1` centralise désormais aussi `default-features = false` sous `[workspace.dependencies]`, car Cargo interdit à une dépendance membre héritée de remplacer cette option. `game-realtime-websocket-lib` ajoute seulement les features locales `sink + std` pour `futures-util` et `connect + handshake` pour `tokio-tungstenite`; aucune feature TLS n'est activée. La gate utilisateur du fix confirme Rust `1.94.1`, Tokio `1.53.1`, tokio-tungstenite/Tungstenite `0.30.0` et un graphe normal sans pile TLS. `alpha.4` ajoute uniquement la feature Tokio `time` au backend afin d'appliquer les deadlines produit.
## Ownership physique retenu
@@ -307,6 +307,38 @@ Le backend ne crée aucun runtime, thread ni task détachée. Le harness d'inté
Aucun `README.md`/`USAGE.md` local n'est ajouté pendant `alpha.3` : la crate reste petite, son API publique est documentée par rustdoc et le présent plan porte encore les décisions durables. Ce choix sera réévalué pendant la consolidation finale conformément à `DOC-CRATE-*`.
## Décisions matérialisées dans `alpha.4`
`game-realtime-websocket-lib` expose désormais `WebSocketConfig` et les variantes configurables `connect_with_config()` et `WebSocketListener::bind_with_config()`. Les wrappers historiques `connect()` et `bind()` conservent des valeurs de baseline explicites :
```text
max message size 1 MiB
max frame size 1 MiB
write buffer target 64 KiB
max write buffer 2 MiB
connect/handshake 10 s
send 5 s
close 2 s
receive idle timeout aucun
```
La configuration refuse une limite nulle, une frame plus grande que le message, un write buffer maximum incapable de contenir le target plus un message maximal et une deadline nulle. Les limites Tungstenite sont transmises aux handshakes client et serveur ; les tailles message/frame sortantes sont également vérifiées avant l'appel au sink afin que le rejet soit déterministe.
`connect_timeout` borne la connexion client et la phase de handshake serveur après accept TCP. Le listener reste volontairement capable d'attendre indéfiniment un nouveau peer : ce temps d'attente appartient au service consommateur, pas à une connexion déjà en établissement. `send_timeout` et `close_timeout` bornent leurs opérations respectives. Après expiration d'un `send`, la moitié émission refuse un nouvel envoi avec `Aborted`, car l'appel interrompu peut avoir progressé partiellement et ne doit pas être rejoué implicitement.
Aucun idle timeout n'est ajouté à `receive()`. Heartbeat, inactivité joueur et politique de session restent au-dessus du transport.
Les tests négatifs `alpha.4` couvrent :
- rejet sortant d'un payload hors limite avant écriture ;
- rejet entrant d'un message/frame hors limite par Tungstenite ;
- rejet d'une frame Text par le contrat binaire ;
- drop TCP/WebSocket sans close handshake, attendu comme erreur de protocole ;
- timeout de handshake serveur avec un peer TCP silencieux ;
- mapping déterministe de `WriteBufferFull` vers `Backpressure` et de `Capacity` vers `MessageTooLarge`.
Un test réseau artificiel de saturation `WriteBufferFull` n'est pas retenu : Tungstenite documente que son write buffer ne dépasse le target que lorsque les écritures sous-jacentes échouent, ce qui rendrait une saturation loopback normale non représentative et potentiellement flaky. La borne finie est néanmoins configurée, le mapping backend est testé unitairement et le timeout d'émission borne l'attente du sink.
## Tests retenus
### Contrat commun
@@ -384,6 +416,16 @@ cargo tree -p game-realtime-websocket-lib --edges normal
Fermer robustesse, limites, timeouts, close/cancellation et cas négatifs. Réexécuter les tests des deux crates. Un demo n'est ajouté que si une preuve manque réellement.
Gates ciblées :
```bash
cargo test -p game-realtime-transport-lib --all-targets --all-features
cargo test -p game-realtime-websocket-lib --all-targets --all-features
cargo tree -p game-realtime-websocket-lib --edges normal
```
Le test backend doit maintenant couvrir le loopback positif, les invariants de configuration, les mappings de capacité/backpressure et les cinq scénarios négatifs déterministes de `robustness.rs`.
### Beta
La beta est le jalon large retenu pour :
@@ -430,15 +472,17 @@ Aucune dépendance réseau n'est ajoutée.
### `0.3.4-alpha.4` — robustesse et consolidation technique
- limites explicites ;
- timeouts ;
- fermeture distante/abrupt drop ;
- `WebSocketConfig` avec limites et deadlines explicites ;
- application symétrique de la configuration aux handshakes client/serveur ;
- timeout connect/handshake, send et close, sans idle timeout transport ;
- fermeture distante propre conservée et abrupt drop distingué ;
- cas Text non supporté ;
- backpressure bore ;
- cancellation/lifecycle sans tâche orpheline ;
- message/frame hors limite ;
- write buffer maximum borné et mapping `Backpressure` testé sans fabriquer un test réseau flaky ;
- lifecycle sans runtime/task backend privé ;
- documentation API/backend et audit du graphe.
Cette tranche peut absorber la consolidation avant beta si elle reste dans le budget. Si elle devient trop lourde, une `alpha.5` de consolidation est créée ; elle ne doit pas être ajoutée uniquement pour suivre un numéro prévu.
Si les gates de cette tranche sont propres, le demo/CLI conditionnel n'apporte plus de preuve supplémentaire : la suite doit privilégier une courte consolidation alpha uniquement si la revue documentaire/API révèle une dette réelle, sinon passer directement à la beta large.
### `0.3.4-beta.1` — validation large