0.3.4-alpha.4
This commit is contained in:
157
deltas/0.3.4/alpha.4.md
Normal file
157
deltas/0.3.4/alpha.4.md
Normal file
@@ -0,0 +1,157 @@
|
||||
<!-- file: deltas/0.3.4/alpha.4.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta 0.3.4-alpha.4
|
||||
|
||||
## Base
|
||||
|
||||
Base directe : `0.3.4-alpha.3.fix.1`, validée par l'utilisateur le 2026-09-21.
|
||||
|
||||
Cette tranche n'élargit pas le contrat transport-neutral et n'introduit ni session gameplay, ni wire codec, ni TLS. Elle ferme les limites, deadlines et principaux cas négatifs du backend WebSocket avant la validation large.
|
||||
|
||||
## Historique du jalon précédent
|
||||
|
||||
Ajout de :
|
||||
|
||||
```text
|
||||
history/0.3.4/alpha.3.fix.1.md
|
||||
```
|
||||
|
||||
L'historique enregistre la gate utilisateur réellement fournie : audits propres, workspace/Clippy propres, sept tests transport, loopback WebSocket propre et graphe normal sans pile TLS.
|
||||
|
||||
## Configuration WebSocket produit
|
||||
|
||||
Ajout de `WebSocketConfig`, réexportée au crate-root de `game-realtime-websocket-lib`.
|
||||
|
||||
Valeurs par défaut :
|
||||
|
||||
```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 peut être ajustée par builders `with_*` puis validée. Les invariants refusent notamment :
|
||||
|
||||
- message/frame de taille nulle ;
|
||||
- frame maximale supérieure au message maximal ;
|
||||
- write buffer maximal incapable de contenir le target plus un message maximal ;
|
||||
- overflow de ce calcul ;
|
||||
- deadline connect/send/close nulle.
|
||||
|
||||
Les wrappers `connect()` et `WebSocketListener::bind()` restent disponibles avec la configuration par défaut. Les nouveaux chemins configurables sont :
|
||||
|
||||
```text
|
||||
connect_with_config(endpoint, config)
|
||||
WebSocketListener::bind_with_config(address, config)
|
||||
```
|
||||
|
||||
## Limites et backpressure
|
||||
|
||||
Les limites message/frame/write-buffer sont transmises à `tungstenite::protocol::WebSocketConfig` aussi bien côté client que côté serveur.
|
||||
|
||||
Le send vérifie également `max_message_size` et `max_frame_size` avant l'écriture afin que le dépassement sortant soit déterministe et remonte `TransportErrorKind::MessageTooLarge` sans dépendre d'un comportement réseau.
|
||||
|
||||
`max_write_buffer_size` est borné à `2 MiB` par défaut. `tungstenite::Error::WriteBufferFull` continue d'être mappé vers `TransportErrorKind::Backpressure` et ce mapping dispose désormais d'un test unitaire dédié. Aucun test loopback ne fabrique une saturation artificielle : le write buffer Tungstenite ne grossit au-delà de son target que lors d'échecs d'écriture sous-jacents, ce qui rendrait ce scénario réseau local non déterministe.
|
||||
|
||||
## Timeouts et lifecycle
|
||||
|
||||
La feature Tokio `time` devient une dépendance de production uniquement pour `game-realtime-websocket-lib`.
|
||||
|
||||
Les deadlines sont appliquées ainsi :
|
||||
|
||||
- connexion client complète : `connect_timeout` ;
|
||||
- handshake serveur après accept TCP : `connect_timeout` ;
|
||||
- émission d'un message : `send_timeout` ;
|
||||
- fermeture locale du sink : `close_timeout`.
|
||||
|
||||
L'attente d'un nouveau peer sur `TcpListener::accept()` n'est volontairement pas bornée par la configuration d'une connexion. `receive()` ne reçoit aucun idle timeout : heartbeat et inactivité appartiennent aux futures couches session/synchronisation.
|
||||
|
||||
Si un send expire, la moitié émission mémorise cet état et refuse un nouvel envoi avec `TransportErrorKind::Aborted`. Le send interrompu peut avoir progressé partiellement ; il ne doit donc jamais être rejoué implicitement comme s'il n'avait rien produit. Une fermeture explicite reste néanmoins tentable avec sa propre deadline.
|
||||
|
||||
Le backend continue de ne créer aucun runtime, thread ou task détachée.
|
||||
|
||||
## Tests ajoutés
|
||||
|
||||
Tests unitaires de configuration :
|
||||
|
||||
- defaults produit exacts ;
|
||||
- limites message/frame/write-buffer invalides ;
|
||||
- deadlines nulles invalides.
|
||||
|
||||
Tests unitaires de mapping backend :
|
||||
|
||||
- `WriteBufferFull -> Backpressure` ;
|
||||
- `Capacity -> MessageTooLarge`.
|
||||
|
||||
Nouveau `tests/robustness.rs` :
|
||||
|
||||
1. payload sortant hors limite rejeté avant écriture ;
|
||||
2. payload entrant hors limite rejeté par Tungstenite ;
|
||||
3. frame Text rejetée par le contrat binaire ;
|
||||
4. peer drop sans close handshake remonté comme erreur de protocole ;
|
||||
5. peer TCP silencieux borné par le timeout de handshake serveur.
|
||||
|
||||
Tous les scénarios réseau utilisent uniquement `127.0.0.1:0` et une borne externe de test de trois secondes.
|
||||
|
||||
## Documentation
|
||||
|
||||
Le plan actif `docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md` est mis à jour avec :
|
||||
|
||||
- validation effective de `alpha.3.fix.1` ;
|
||||
- configuration et deadlines retenues ;
|
||||
- raison de l'absence d'idle timeout transport ;
|
||||
- stratégie backpressure testable sans test réseau flaky ;
|
||||
- orientation vers beta ou courte consolidation selon le résultat réel de cette gate.
|
||||
|
||||
`CHANGELOG.md` et `ROADMAP.md` restent inchangés : la version est encore en alpha et le scope macroscopique `0.3.4` ne change pas.
|
||||
|
||||
## Fichiers
|
||||
|
||||
Modifiés :
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
README.md
|
||||
crates/common/game-realtime-websocket-lib/Cargo.toml
|
||||
crates/common/game-realtime-websocket-lib/src/lib.rs
|
||||
crates/common/game-realtime-websocket-lib/src/websocket.rs
|
||||
docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md
|
||||
```
|
||||
|
||||
Ajoutés :
|
||||
|
||||
```text
|
||||
crates/common/game-realtime-websocket-lib/src/config.rs
|
||||
crates/common/game-realtime-websocket-lib/unit_tests/config.rs
|
||||
crates/common/game-realtime-websocket-lib/unit_tests/websocket.rs
|
||||
crates/common/game-realtime-websocket-lib/tests/robustness.rs
|
||||
history/0.3.4/alpha.3.fix.1.md
|
||||
deltas/0.3.4/alpha.4.md
|
||||
```
|
||||
|
||||
## Validation attendue
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
cargo fmt --all -- --check
|
||||
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates Android Web deltas history
|
||||
python3 scripts/audit_distribution_layout.py
|
||||
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
La validation utilisateur reste autoritaire pour la compilation, Clippy et les tests runtime. Les audits statiques exécutables dans l'environnement de génération doivent être propres avant livraison du delta.
|
||||
Reference in New Issue
Block a user