v0.3.14-pre.010
This commit is contained in:
273
deltas/0.3.14/pre.010.md
Normal file
273
deltas/0.3.14/pre.010.md
Normal file
@@ -0,0 +1,273 @@
|
||||
<!-- file: deltas/0.3.14/pre.010.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.3.14-pre.010` — backpressure et fairness nominal / repair
|
||||
|
||||
## Base requise
|
||||
|
||||
```text
|
||||
0.3.14-pre.009-fix.002
|
||||
workspace.package.version = 0.3.14-pre.9.fix.2
|
||||
deltas/0.3.14/pre.009-fix.002.md présent
|
||||
```
|
||||
|
||||
## Gate de la base
|
||||
|
||||
Le gate opérateur de `0.3.14-pre.009-fix.002` est validé avant ouverture de cette tranche :
|
||||
|
||||
```text
|
||||
cargo fmt --all : PASS
|
||||
cargo fmt --all -- --check : PASS
|
||||
audit Rust workspace rules : PASS
|
||||
audit Markdown tables : PASS
|
||||
cargo check --workspace : PASS
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features : PASS
|
||||
```
|
||||
|
||||
Le gate Worker comprend notamment :
|
||||
|
||||
```text
|
||||
143 unit tests : PASS
|
||||
cross_layer_completeness : 8 PASS
|
||||
dependency_boundary : 19 PASS
|
||||
hardening : 34 PASS
|
||||
public_api : 20 PASS
|
||||
release_completeness : 11 PASS
|
||||
```
|
||||
|
||||
## Objectif
|
||||
|
||||
Implémenter strictement la tranche `pre.010` du plan `035` :
|
||||
|
||||
```text
|
||||
conserver une admission Common RAW centrale unique
|
||||
conserver un pipeline de persistence unique et ses limites existantes
|
||||
faire partager au trafic nominal et repair le registre/coalescence global d'hydration existant
|
||||
ordonner nominal/repair sans réserver une fraction fixe de capacité
|
||||
permettre la progression lorsque la capacité existante vaut 1
|
||||
borner le burst repair lorsqu'un nominal attend
|
||||
conserver un fanout logique getBlock <= 4
|
||||
conserver les fenêtres HTTP <= 512 slots
|
||||
ne créer aucun second pool Store, aucune seconde queue d'admission et aucun second registre d'hydration
|
||||
```
|
||||
|
||||
## Arbitre privé nominal / repair
|
||||
|
||||
`runtime_resources.rs` introduit un arbitre privé source-neutral :
|
||||
|
||||
```text
|
||||
RawTransactionIngestTrafficClass
|
||||
Nominal
|
||||
Repair
|
||||
|
||||
RawTransactionIngestFairTurnGate
|
||||
```
|
||||
|
||||
Les waiters reçoivent des tickets monotones checked. La queue d'attente est bornée par la capacité déjà attribuée au registre global d'hydration ; aucun waiter pool illimité n'est ajouté.
|
||||
|
||||
Lorsque les deux classes attendent :
|
||||
|
||||
```text
|
||||
premier arbitrage -> Nominal
|
||||
après Nominal -> Repair
|
||||
après Repair -> Nominal
|
||||
```
|
||||
|
||||
Le burst repair maximal en présence de nominal est donc :
|
||||
|
||||
```text
|
||||
MAX_RAW_TRANSACTION_INGEST_REPAIR_BURST = 1
|
||||
```
|
||||
|
||||
Si une seule classe attend, elle progresse sans attendre artificiellement l'autre classe. Le mécanisme ne réserve donc jamais une capacité inexistante.
|
||||
|
||||
## Hydration globale partagée
|
||||
|
||||
Le `RawTransactionIngestGlobalHydrationRegistry` reste unique.
|
||||
|
||||
Le même sémaphore :
|
||||
|
||||
```text
|
||||
hydration_permits
|
||||
```
|
||||
|
||||
est maintenant précédé par l'arbitre nominal/repair. Le chemin live existant acquiert explicitement :
|
||||
|
||||
```text
|
||||
RawTransactionIngestTrafficClass::Nominal
|
||||
```
|
||||
|
||||
La classe `Repair` utilise la même primitive d'acquisition et le même sémaphore ; aucun `RepairHydrationRegistry`, aucune seconde semaphore d'hydration et aucune seconde coalescence ne sont créés.
|
||||
|
||||
L'arbitre gouverne l'ordre d'accès au permit ; le permit lui-même reste détenu pendant l'I/O comme auparavant. Les bornes globales existantes restent donc l'autorité de concurrence.
|
||||
|
||||
## Faible capacité et fanout HTTP
|
||||
|
||||
La validation run-local accepte explicitement :
|
||||
|
||||
```text
|
||||
admission_queue_capacity = 1
|
||||
persistence_concurrency = 1
|
||||
```
|
||||
|
||||
Le fanout bloc repair dérive uniquement de la capacité existante :
|
||||
|
||||
```text
|
||||
repair_block_fetch_limit(existing_capacity) = min(existing_capacity, 4)
|
||||
```
|
||||
|
||||
Donc :
|
||||
|
||||
```text
|
||||
capacité 1 -> fanout 1
|
||||
capacité 4 -> fanout 4
|
||||
capacité 64 -> fanout 4
|
||||
```
|
||||
|
||||
Aucun worker ou permit n'est réservé à l'avance pour le repair. La borne historique reste également :
|
||||
|
||||
```text
|
||||
MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS = 1
|
||||
MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT = 4
|
||||
MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS = 512
|
||||
```
|
||||
|
||||
## Admission et persistence
|
||||
|
||||
Cette tranche ne crée aucune nouvelle `mpsc::channel` dans `runtime_resources.rs`.
|
||||
|
||||
Tout matériau Common RAW continue à utiliser :
|
||||
|
||||
```text
|
||||
RawTransactionAdmission
|
||||
la Sender centrale existante
|
||||
le pipeline de persistence existant
|
||||
la même persistence_concurrency
|
||||
```
|
||||
|
||||
La fairness ajoutée ne contourne donc ni backpressure admission ni convergence/persistence Store.
|
||||
|
||||
## Compteurs et overflow
|
||||
|
||||
Les tickets de fairness utilisent `checked_add`. Un épuisement de ticket ou un dépassement de la queue de waiters produit une erreur Worker stable ; aucun `saturating_add` n'est utilisé pour masquer un overflow.
|
||||
|
||||
L'annulation d'un waiter retire son ticket de l'arbitre. La libération d'un turn réveille les waiters restants sans conserver de `std::sync::MutexGuard` à travers un `await`.
|
||||
|
||||
## Tests ajoutés
|
||||
|
||||
Les unit tests Worker couvrent :
|
||||
|
||||
```text
|
||||
alternance Nominal -> Repair -> Nominal lorsque les deux classes attendent
|
||||
burst repair borné à 1
|
||||
queue de waiters bornée et libérée après annulation/drop
|
||||
fanout bloc min(capacité, 4)
|
||||
partage réel du même semaphore d'hydration entre Nominal et Repair
|
||||
blocage Repair tant que le permit capacity=1 est occupé par Nominal
|
||||
progression Repair seul avec capacity=1
|
||||
```
|
||||
|
||||
Les canaris `hardening` et `release_completeness` vérifient en plus :
|
||||
|
||||
```text
|
||||
une seule admission mpsc centrale
|
||||
un seul RawTransactionIngestGlobalHydrationRegistry
|
||||
absence de RepairHydrationRegistry
|
||||
bornes 4 getBlock / 512 slots conservées
|
||||
aucune fuite publique des classes ou de l'arbitre de fairness
|
||||
```
|
||||
|
||||
## Hors périmètre inchangé
|
||||
|
||||
```text
|
||||
aucune nouvelle snapshot publique de gap/repair avant pre.011
|
||||
aucun changement de health policy pre.009
|
||||
aucun nouveau mécanisme replay/reconnect Worker
|
||||
aucun respawn de source
|
||||
aucun EARLY/shred
|
||||
aucun Job Backfill depuis Worker
|
||||
aucun nouveau provider ou SDK
|
||||
aucune nouvelle dépendance
|
||||
```
|
||||
|
||||
## Fichiers ajoutés
|
||||
|
||||
```text
|
||||
deltas/0.3.14/pre.010.md
|
||||
```
|
||||
|
||||
## Fichiers modifiés
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
|
||||
crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
|
||||
crates/ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs
|
||||
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs
|
||||
```
|
||||
|
||||
## Fichiers supprimés
|
||||
|
||||
```text
|
||||
aucun
|
||||
```
|
||||
|
||||
## Version Cargo
|
||||
|
||||
Conformément à `VER-ID-009` :
|
||||
|
||||
```text
|
||||
header Cargo.toml : 581 -> 582
|
||||
workspace.package.version : 0.3.14-pre.9.fix.2 -> 0.3.14-pre.10
|
||||
```
|
||||
|
||||
Versions des fichiers modifiés :
|
||||
|
||||
```text
|
||||
runtime_resources.rs : 39 (bump depuis 38)
|
||||
unit_tests/runtime_resources.rs : 32 (bump depuis 31)
|
||||
tests/hardening.rs : 34 (bump depuis 33)
|
||||
tests/release_completeness.rs : 29 (bump depuis 28)
|
||||
```
|
||||
|
||||
## Validation exécutée dans l'environnement de préparation
|
||||
|
||||
```text
|
||||
python3 scripts/audit_rust_workspace_rules.py : PASS
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas : PASS
|
||||
scan des frontières Worker/Transport/Backfill/Store : PASS
|
||||
scan de la crate-root historique : PASS
|
||||
comparaison exacte pre.009-fix.002 -> pre.010 : PASS
|
||||
```
|
||||
|
||||
Les gates Cargo ne sont pas déclarés PASS dans l'environnement de préparation lorsqu'ils ne peuvent pas y être exécutés. Ils restent obligatoires côté opérateur avant `pre.011`.
|
||||
|
||||
## Décisions prises
|
||||
|
||||
```text
|
||||
fairness temporelle/alternée et non réservation de pourcentage
|
||||
burst repair = 1 lorsque nominal attend
|
||||
classe seule autorisée à progresser immédiatement
|
||||
hydration nominal et repair sur le même registre + semaphore
|
||||
fanout bloc dérivé de la capacité existante et plafonné à 4
|
||||
aucune nouvelle queue admission/persistence
|
||||
```
|
||||
|
||||
## Questions ouvertes
|
||||
|
||||
```text
|
||||
aucune pour cette tranche
|
||||
```
|
||||
|
||||
## Gate opérateur après application
|
||||
|
||||
```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 deltas
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features
|
||||
```
|
||||
Reference in New Issue
Block a user