Files
khadhroony-solana-project/deltas/0.1.2/pre.004-fix.001.md

158 lines
4.3 KiB
Markdown

<!-- file: deltas/0.1.2/pre.004-fix.001.md -->
<!-- version: 1 -->
# Delta 0.1.2-pre.004-fix.001
## Base requise
Livraison précédente :
```text
0.1.2-pre.004
```
La base porte :
```text
workspace.package.version = "0.1.2-pre.4"
Cargo.toml header version = 31
```
## Validations remontées
Les validations utilisateur de `pre.004` sont :
```text
cargo fmt --all OK
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test --workspace ECHEC
cargo tree -p ksp-logging-lib OK
cargo tree -p ksp-logging-lib -d OK — aucun doublon
cargo tree -p ksp-logging-lib -e features inspecté
```
Tous les tests unitaires, de callsite et de façade publique passent. Le seul échec est :
```text
global_runtime_supports_takeover_non_blocking_outputs_hot_reload_and_single_initialization
```
sur :
```text
assertion failed: file_text.contains("file output marker")
```
Le test émet une ligne sur le sink fichier, retire immédiatement ce sink par hot reload, puis lit le fichier. Il constitue donc un test direct du contrat de drain/flush lors d'un reload.
## Cause de lifecycle
`pre.004` faisait conceptuellement :
```text
reload_handle.reload(new_layers)
retire counters
replace outputs
drop(old WorkerGuard)
```
Le layer `fmt` retiré possède les clones `NonBlocking` utilisés pour alimenter le worker. KSP ne récupérait cependant pas explicitement l'ancien `Vec` de layers ; l'ordre entre la destruction effective de ces anciens layers et la destruction des `WorkerGuard` n'était donc pas exprimé dans notre lifecycle.
Pour un sink non bloquant, l'ordre voulu est explicite :
```text
1. préparer complètement le nouveau runtime
2. remplacer le Vec actif et récupérer l'ancien Vec
3. mémoriser les dropped-line counters
4. remplacer les outputs actifs
5. détruire les anciens layers / NonBlocking senders
6. détruire les anciens WorkerGuard
7. retourner du reinitialize()
```
`WorkerGuard` envoie le signal de shutdown au worker et attend son drain/flush de manière bornée. Les anciens senders doivent donc être libérés avant cette étape lorsqu'un sink vient d'être retiré.
## Correction
`reinitialize()` n'utilise plus :
```text
Handle::reload(new_layers)
```
pour les changements de runtime.
Il utilise :
```text
Handle::modify(... mem::replace(active_layers, new_layers) ...)
```
et récupère ainsi l'ancien `RuntimeLayers`.
Après succès du swap :
```text
drop(retired_layers)
drop(retired_outputs)
```
est exécuté dans cet ordre.
Cette correction :
- ne change pas l'API publique ;
- conserve le subscriber global unique ;
- conserve le takeover KSP ;
- conserve la préparation transactionnelle des nouveaux sinks avant le swap ;
- conserve l'ancienne configuration lorsqu'une validation ou une construction de sink échoue avant le swap ;
- rend explicite le lifecycle de retrait des `NonBlocking` writers avant leurs `WorkerGuard` ;
- évite d'ajouter un sleep ou un polling temporel au test.
Le test d'intégration qui a révélé le défaut reste inchangé et sert directement de test de non-régression.
## Référence backend
`tracing-appender 0.2.5` documente `WorkerGuard` comme responsable du flush des logs bufferisés à sa destruction. Son implémentation de `Drop` envoie un `Msg::Shutdown` au worker puis attend le signal de fin de drain de manière bornée. KSP doit donc contrôler clairement l'ordre de destruction des senders/layers et du guard au moment d'un hot reload.
## Version technique
Ce correctif modifie du Rust. La version workspace devient :
```text
workspace.package.version = "0.1.2-pre.4.fix.1"
```
et l'en-tête du `Cargo.toml` racine devient :
```text
# version: 32
```
## Fichiers du delta
```text
Cargo.toml
crates/ksp-logging-lib/src/runtime.rs
docs/plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md
deltas/0.1.2/pre.004-fix.001.md
```
## Validations à exécuter
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
```
Le graphe Cargo/features de `pre.004` a déjà été remonté sans doublon. Il pourra être réaudité dans `pre.005` avec les validations d'intégration finales.
Si ces validations sont propres, la tranche suivante reste :
```text
0.1.2-pre.005 — intégration + concurrence + saturation + audits
```