238 lines
6.6 KiB
Markdown
238 lines
6.6 KiB
Markdown
<!-- file: deltas/0.3.14/pre.012.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.3.14-pre.012` — hardening races / shutdown
|
|
|
|
## Base requise
|
|
|
|
```text
|
|
0.3.14-pre.011-fix.002
|
|
workspace.package.version = 0.3.14-pre.11.fix.2
|
|
deltas/0.3.14/pre.011-fix.002.md présent
|
|
```
|
|
|
|
## Gate de la base
|
|
|
|
Le gate opérateur de `0.3.14-pre.011-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
|
|
150 unit tests : PASS
|
|
cross_layer_completeness : 8 PASS
|
|
dependency_boundary : 19 PASS
|
|
hardening : 36 PASS
|
|
public_api : 21 PASS
|
|
release_completeness : 13 PASS
|
|
```
|
|
|
|
## Objectif
|
|
|
|
Implémenter strictement la tranche `pre.012` du plan `035` :
|
|
|
|
```text
|
|
borner stop/fault pendant les sous-tâches source et les phases de continuité
|
|
préserver la première faute quand un sibling ne coopère pas au shutdown
|
|
abandonner et rejoindre les tâches source restantes après expiration de la deadline
|
|
empêcher une mutation de coverage après observation d'un stop HTTP
|
|
empêcher une hydration déjà jointe de poursuivre admission/continuity après observation d'un stop
|
|
conserver le drain/abort/join global déjà validé pour admission/persistence
|
|
ne créer aucun task pool, pipeline, timeout ou ownership parallèle
|
|
```
|
|
|
|
## Drain interne des sources désormais borné
|
|
|
|
Avant cette tranche, le drain global Worker était borné par `shutdown_drain_timeout`, mais le superviseur interne des sources pouvait encore attendre indéfiniment un sibling non coopératif après une faute de source.
|
|
|
|
`supervise_live_source_tasks` reçoit maintenant la même deadline déjà configurée dans `RawTransactionIngestSettings` :
|
|
|
|
```text
|
|
settings.shutdown_drain_timeout()
|
|
```
|
|
|
|
`drain_live_source_tasks` applique :
|
|
|
|
```text
|
|
tokio::time::timeout(shutdown_drain_timeout, drain)
|
|
```
|
|
|
|
En cas d'expiration :
|
|
|
|
```text
|
|
children.abort_all()
|
|
join de tous les children annulés
|
|
```
|
|
|
|
Aucune tâche source ne reste donc détenue après retour du superviseur interne.
|
|
|
|
## Priorité de faute
|
|
|
|
Si le shutdown interne commence après une faute source déjà observée et que le sibling ne coopère pas avant la deadline :
|
|
|
|
```text
|
|
la première faute source reste la faute retournée
|
|
```
|
|
|
|
Le timeout ne remplace pas une cause terminale déjà connue.
|
|
|
|
Si aucun défaut antérieur n'existe et qu'un stop coopératif ne peut pas joindre une source avant la deadline :
|
|
|
|
```text
|
|
ERROR_CODE_RAW_TRANSACTION_INGEST_DRAIN_TIMEOUT
|
|
```
|
|
|
|
est retourné.
|
|
|
|
Cette règle aligne le superviseur source avec le drain Worker global déjà validé.
|
|
|
|
## Stop avant mutation de coverage HTTP
|
|
|
|
Le polling HTTP vérifie maintenant explicitement le stop après le traitement des blocs découverts et avant :
|
|
|
|
```text
|
|
record_coverage_epoch(...)
|
|
processing_frontier.publish()
|
|
```
|
|
|
|
Un stop déjà observé ne peut donc pas être suivi d'une nouvelle preuve de coverage de cette fenêtre.
|
|
|
|
Les appels réseau restent stop-preemptible via les `tokio::select!` existants ; aucun retry Worker n'est ajouté.
|
|
|
|
## Stop pendant hydration/admission
|
|
|
|
`RawTransactionIngestHydrationCoordinator::handle_joined` vérifie maintenant le stop :
|
|
|
|
```text
|
|
avant de retirer/appliquer le résultat d'hydration joint
|
|
avant chaque signal coalescé de ce résultat
|
|
```
|
|
|
|
Les `tokio::select!` existants restent en place autour de l'admission async.
|
|
|
|
Un stop déjà observé ne poursuit donc pas la mutation continuity ou l'admission d'un résultat d'hydration devenu prêt au même moment.
|
|
|
|
## Invariants préservés
|
|
|
|
```text
|
|
Transport reste propriétaire des sockets, reconnects et replay natif
|
|
Worker ne modifie jamais from_slot
|
|
aucun respawn de source
|
|
aucun second scheduler ou sémaphore
|
|
fairness pre.010 inchangée
|
|
observabilité pre.011 inchangée
|
|
Common RAW/admission/persistence restent uniques
|
|
Store reste accessible via ksp-store-lib seulement
|
|
aucun Worker -> Config/Job/backend Store
|
|
aucune nouvelle dépendance
|
|
```
|
|
|
|
## Tests ajoutés
|
|
|
|
Deux canaris runtime reproduisent les races que cette tranche ferme :
|
|
|
|
```text
|
|
v0_3_14_pre_012_source_fault_preserves_first_fault_and_aborts_non_cooperative_sibling
|
|
v0_3_14_pre_012_stop_aborts_non_cooperative_source_after_bounded_drain
|
|
```
|
|
|
|
Le premier prouve :
|
|
|
|
```text
|
|
sibling réellement démarré
|
|
faute source observée
|
|
sibling volontairement non coopératif
|
|
deadline interne atteinte
|
|
abort + join du sibling
|
|
première faute préservée
|
|
aucune tâche active après retour
|
|
```
|
|
|
|
Le second prouve :
|
|
|
|
```text
|
|
stop coopératif demandé
|
|
source volontairement non coopérative
|
|
deadline interne atteinte
|
|
ERROR_CODE_RAW_TRANSACTION_INGEST_DRAIN_TIMEOUT
|
|
abort + join
|
|
aucune tâche active après retour
|
|
```
|
|
|
|
Les canaris `hardening`, `dependency_boundary` et `release_completeness` vérifient en plus :
|
|
|
|
```text
|
|
deadline source et deadline Worker présentes
|
|
abort_all + join présents aux deux niveaux
|
|
checkpoints stop avant les mutations repair/admission concernées
|
|
aucune nouvelle dépendance ni frontière backend
|
|
aucune croissance de surface publique shutdown
|
|
```
|
|
|
|
## Hors périmètre inchangé
|
|
|
|
```text
|
|
aucune nouvelle stratégie de repair
|
|
aucune nouvelle méthode HTTP
|
|
aucun changement de health policy
|
|
aucun changement de snapshot public
|
|
aucun changement de TargetCoverage
|
|
aucun changement de fairness
|
|
aucun changement de persistence semantics
|
|
aucun EARLY/shred
|
|
aucun Job Backfill depuis Worker
|
|
```
|
|
|
|
## Fichiers ajoutés
|
|
|
|
```text
|
|
deltas/0.3.14/pre.012.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/unit_tests/runtime_resources.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/tests/dependency_boundary.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
|
|
crates/ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs
|
|
```
|
|
|
|
## Fichiers supprimés
|
|
|
|
```text
|
|
aucun
|
|
```
|
|
|
|
## Version Cargo
|
|
|
|
Conformément au workflow prerelease non-fix :
|
|
|
|
```text
|
|
header Cargo.toml : 586 -> 587
|
|
workspace.package.version : 0.3.14-pre.11.fix.2 -> 0.3.14-pre.12
|
|
```
|
|
|
|
## 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
|
|
```
|