158 lines
4.3 KiB
Markdown
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
|
|
```
|