v0.1.2-pre.005-fix.001

This commit is contained in:
2026-08-14 20:08:18 +02:00
parent ea87a58e32
commit d96f41fb8e
4 changed files with 95 additions and 5 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml # file: Cargo.toml
# version: 36 # version: 37
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["crates/ksp-core-lib", "crates/ksp-logging-lib"] members = ["crates/ksp-core-lib", "crates/ksp-logging-lib"]
[workspace.package] [workspace.package]
version = "0.1.2-pre.5" version = "0.1.2-pre.5.fix.1"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-logging-lib/tests/runtime.rs // file: crates/ksp-logging-lib/tests/runtime.rs
// version: 3 // version: 4
//! Integration tests for global initialization, takeover filtering, non-blocking outputs and hot reload. //! Integration tests for global initialization, takeover filtering, non-blocking outputs and hot reload.
@@ -69,6 +69,8 @@ fn exercise_concurrent_reload(guard: &mut ksp_logging_lib::LoggingGuard, disable
std::option::Option::Some(ksp_logging_lib::ConsoleSettings::stderr()), std::option::Option::Some(ksp_logging_lib::ConsoleSettings::stderr()),
std::option::Option::None, std::option::Option::None,
); );
let quiet_reload = ksp_logging_lib::reinitialize(guard, &quiet_console);
assert!(quiet_reload.is_ok());
let stop = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)); let stop = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let barrier = std::sync::Arc::new(std::sync::Barrier::new(5)); let barrier = std::sync::Arc::new(std::sync::Barrier::new(5));
let mut threads = std::vec::Vec::new(); let mut threads = std::vec::Vec::new();

View File

@@ -0,0 +1,88 @@
<!-- file: deltas/0.1.2/pre.005-fix.001.md -->
<!-- version: 1 -->
# Delta 0.1.2-pre.005-fix.001
## Base requise
Livraison précédente :
```text
0.1.2-pre.005
```
La base porte :
```text
workspace.package.version = "0.1.2-pre.5"
Cargo.toml header version = 36
```
## Validation remontée
La validation utilisateur de `pre.005` est fonctionnellement propre :
```text
cargo fmt --all OK
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test --workspace OK
cargo test -p ksp-logging-lib --test overhead -- --ignored --nocapture OK
```
Le probe d'overhead a également passé son garde-fou grossier sur 200000 itérations.
Le test runtime concurrent produit toutefois un grand volume de lignes `TRACE` sur stderr au démarrage du stress test. Le runtime est encore sur la configuration précédente `console_enabled` avec un override `Trace` lorsque les producteurs sont libérés ; ils peuvent donc émettre avant le premier reload vers la configuration silencieuse.
## Correction
`exercise_concurrent_reload` effectue maintenant un `reinitialize` vers `quiet_console` **avant** de créer/libérer les producteurs concurrents.
Le stress test conserve ensuite exactement :
- 4 producteurs ;
- les appels continus à `ksp_logging_lib::trace!` ;
- 32 hot reloads ;
- l'alternance entre console non bloquante présente avec filtre KSP `Off` et runtime sans sink ;
- les assertions de succès des reloads et des joins.
La correction supprime uniquement la fenêtre de course initiale qui laissait la configuration `Trace` précédente produire des lignes. Elle ne modifie aucun comportement de production, aucune API publique et aucune dépendance.
## Version technique
Ce correctif modifie un fichier Rust de test. La version workspace devient :
```text
workspace.package.version = "0.1.2-pre.5.fix.1"
```
et l'en-tête du `Cargo.toml` racine devient :
```text
# version: 37
```
## Fichiers du delta
```text
Cargo.toml
crates/ksp-logging-lib/tests/runtime.rs
docs/plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md
deltas/0.1.2/pre.005-fix.001.md
```
## Validations à exécuter
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
cargo test -p ksp-logging-lib --test overhead -- --ignored --nocapture
```
Si ces validations sont propres et que le test runtime ne pollue plus la console, `pre.005` est clôturée et la tranche suivante reste :
```text
0.1.2-pre.006 — validation finale, documentation, cleanup et prompt 0.1.3
```

View File

@@ -1,11 +1,11 @@
<!-- file: docs/plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md --> <!-- file: docs/plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md -->
<!-- version: 12 --> <!-- version: 13 -->
# Plan KSP 0.1.2 — Logging foundation # Plan KSP 0.1.2 — Logging foundation
## Statut ## Statut
Plan actif de `0.1.2`, établi par `0.1.2-pre.001`, corrigé par `0.1.2-pre.001-fix.001`, concrétisé par la façade de `0.1.2-pre.002`, étendu au runtime subscriber par `0.1.2-pre.003`/`pre.003-fix.001`, puis complété et corrigé par `pre.004`/`pre.004-fix.001..004`. `pre.005` ouvre la phase d'intégration/robustesse : saturation déterministe, concurrence pendant hot reload, audit de takeover, validation des spans de timing, documentation de crate et probe d'overhead grossier. Plan actif de `0.1.2`, établi par `0.1.2-pre.001`, corrigé par `0.1.2-pre.001-fix.001`, concrétisé par la façade de `0.1.2-pre.002`, étendu au runtime subscriber par `0.1.2-pre.003`/`pre.003-fix.001`, puis complété et corrigé par `pre.004`/`pre.004-fix.001..004`. `pre.005` ouvre la phase d'intégration/robustesse : saturation déterministe, concurrence pendant hot reload, audit de takeover, validation des spans de timing, documentation de crate et probe d'overhead grossier. `pre.005-fix.001` corrige uniquement la pollution console du stress test concurrent : le runtime est désormais placé sur la configuration console silencieuse avant la libération des producteurs, puis les 32 reloads concurrents restent inchangés.
`pre.003-fix.001` a été validé dans l'environnement de développement avec `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --workspace --all-targets` et `cargo test --workspace` propres sur la version Cargo `0.1.2-pre.3.fix.1`. `pre.004` ajoute `tracing-appender`, remplace la console synchrone par un writer non bloquant, introduit le fichier `Never/Hourly/Daily`, possède les `WorkerGuard`, expose des compteurs cumulés de dropped lines, déporte le stripping ANSI côté worker fichier et conserve le hot reload transactionnel des sinks. `pre.004-fix.001` a rendu explicite le retrait des anciens layers avant leurs `WorkerGuard`, mais la validation utilisateur après `cargo clean` a reproduit exactement le même échec du marqueur fichier. Cette seconde validation a invalidé l'hypothèse selon laquelle ce défaut précis provenait du drain. La cause réelle est la sanitization ANSI native de `tracing-subscriber 0.3.23`, activée par défaut dans `fmt::Layer` : elle transforme les séquences de contrôle présentes dans les valeurs avant qu'elles n'atteignent le writer. `pre.004-fix.002` la conserve pour la console mais la désactive sur le formatter fichier afin que le `StripAnsiWriter` KSP, placé côté worker, reçoive les séquences ANSI originales et les supprime réellement. Le lifecycle explicite de `fix.001` est conservé car il reste correct pour le retrait des sinks non bloquants. La validation de `pre.004-fix.002` confirme ensuite que l'écriture fichier et le stripping ANSI fonctionnent, mais révèle que le target externe `sqlx` est encore persisté. La cause est la composition du filtre global comme enfant frère des formatters dans un `Vec<Layer>` : le `Vec` agrège l'intérêt de callsite en conservant l'intérêt le plus élevé de ses enfants, de sorte qu'un formatter intéressé peut masquer le `Interest::never()` du `Targets`. `pre.004-fix.003` compose donc `Targets` devant le `Vec` des sinks avec `Layer::and_then`; le filtre redevient global pour tout le groupe de sorties sans utiliser `with_filter`/`Filtered`. La validation de `pre.004-fix.003` confirme que tous les tests workspace passent, y compris le takeover externe et le fichier non bloquant, mais `cargo clippy --workspace --all-targets` signale encore `vec_init_then_push` dans la construction du composite reloadable. `pre.004-fix.004` applique uniquement cette correction de forme sans modifier le comportement runtime. La validation utilisateur finale de `pre.004-fix.004` sur `0.1.2-pre.4.fix.4` confirme `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --workspace --all-targets` et `cargo test --workspace` propres ; le test runtime global passe avec takeover, fichier non bloquant, stripping ANSI et hot reload. Le graphe Cargo exécuté durant `pre.004` ne présentait aucun doublon et aucune activation KSP de `tracing-attributes`, `tracing-log`, `env-filter`, JSON/Serde ou ANSI formatter ; les dépendances n'ayant pas changé depuis, `pre.005` doit néanmoins refaire ces commandes avant validation de tranche. `pre.003-fix.001` a été validé dans l'environnement de développement avec `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --workspace --all-targets` et `cargo test --workspace` propres sur la version Cargo `0.1.2-pre.3.fix.1`. `pre.004` ajoute `tracing-appender`, remplace la console synchrone par un writer non bloquant, introduit le fichier `Never/Hourly/Daily`, possède les `WorkerGuard`, expose des compteurs cumulés de dropped lines, déporte le stripping ANSI côté worker fichier et conserve le hot reload transactionnel des sinks. `pre.004-fix.001` a rendu explicite le retrait des anciens layers avant leurs `WorkerGuard`, mais la validation utilisateur après `cargo clean` a reproduit exactement le même échec du marqueur fichier. Cette seconde validation a invalidé l'hypothèse selon laquelle ce défaut précis provenait du drain. La cause réelle est la sanitization ANSI native de `tracing-subscriber 0.3.23`, activée par défaut dans `fmt::Layer` : elle transforme les séquences de contrôle présentes dans les valeurs avant qu'elles n'atteignent le writer. `pre.004-fix.002` la conserve pour la console mais la désactive sur le formatter fichier afin que le `StripAnsiWriter` KSP, placé côté worker, reçoive les séquences ANSI originales et les supprime réellement. Le lifecycle explicite de `fix.001` est conservé car il reste correct pour le retrait des sinks non bloquants. La validation de `pre.004-fix.002` confirme ensuite que l'écriture fichier et le stripping ANSI fonctionnent, mais révèle que le target externe `sqlx` est encore persisté. La cause est la composition du filtre global comme enfant frère des formatters dans un `Vec<Layer>` : le `Vec` agrège l'intérêt de callsite en conservant l'intérêt le plus élevé de ses enfants, de sorte qu'un formatter intéressé peut masquer le `Interest::never()` du `Targets`. `pre.004-fix.003` compose donc `Targets` devant le `Vec` des sinks avec `Layer::and_then`; le filtre redevient global pour tout le groupe de sorties sans utiliser `with_filter`/`Filtered`. La validation de `pre.004-fix.003` confirme que tous les tests workspace passent, y compris le takeover externe et le fichier non bloquant, mais `cargo clippy --workspace --all-targets` signale encore `vec_init_then_push` dans la construction du composite reloadable. `pre.004-fix.004` applique uniquement cette correction de forme sans modifier le comportement runtime. La validation utilisateur finale de `pre.004-fix.004` sur `0.1.2-pre.4.fix.4` confirme `cargo fmt --all`, `cargo check --workspace`, `cargo clippy --workspace --all-targets` et `cargo test --workspace` propres ; le test runtime global passe avec takeover, fichier non bloquant, stripping ANSI et hot reload. Le graphe Cargo exécuté durant `pre.004` ne présentait aucun doublon et aucune activation KSP de `tracing-attributes`, `tracing-log`, `env-filter`, JSON/Serde ou ANSI formatter ; les dépendances n'ayant pas changé depuis, `pre.005` doit néanmoins refaire ces commandes avant validation de tranche.