3.9 KiB
Delta 0.1.2-pre.004-fix.003
Base requise
Livraison précédente :
0.1.2-pre.004-fix.002
La base porte :
workspace.package.version = "0.1.2-pre.4.fix.2"
Cargo.toml header version = 33
Validation remontée
Après application de pre.004-fix.002 :
cargo fmt --all OK
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
cargo test --workspace ECHEC
Le marqueur fichier précédemment absent est désormais correctement persisté et les assertions de présence du target, du callsite et d'absence d'ANSI passent. Le test runtime global échoue plus loin sur :
assertion failed: !file_text.contains("external marker must remain silent")
Le défaut restant concerne donc exclusivement le takeover : un événement tracing émis directement avec le target externe sqlx atteint encore le sink fichier alors que la politique KSP exige son silence total.
Cause réelle
pre.003-fix.001 avait évité le panic Filtered/FilterId en plaçant Targets comme layer global distinct dans le même :
Vec<Box<dyn Layer<Registry>>>
que les formatters.
Cette composition n'est toutefois pas correcte pour le filtrage global au niveau des callsites. L'implémentation Layer de Vec<L> agrège register_callsite en conservant l'intérêt le plus élevé retourné par ses enfants. Un fmt::Layer intéressé par le callsite peut donc produire un intérêt actif alors que Targets retourne Interest::never() pour un target externe.
Lorsque le callsite est enregistré comme toujours actif, enabled() n'est ensuite pas consulté à chaque émission. Le Targets frère du formatter ne peut donc plus bloquer l'événement externe.
Le test avec sqlx expose précisément cette fuite.
Correction
Les layers de sortie sont d'abord construits dans un Vec :
outputs
├── console fmt layer, si actif
└── file fmt layer, si actif
Le takeover est ensuite composé devant tout ce groupe :
Targets
.and_then(outputs)
et ce composite unique devient l'élément du Vec reloadable :
reload::Layer
└── Vec
└── Targets -> output layers
Cette forme rétablit la sémantique de filtre global : un Interest::never() produit par Targets court-circuite le groupe de sinks avant leur formatter.
Elle conserve simultanément les propriétés requises :
- aucun
Layer::with_filtern'est utilisé sur un layer remplacé à chaud ; - aucun
Filteredet donc aucunFilterIdreloadable n'est introduit ; - console et fichier restent activables/désactivables dynamiquement ;
Handle::modifycontinue de récupérer l'ancien composite avant destruction de sesWorkerGuard;- la sanitization console et le stripping ANSI fichier de
fix.002restent inchangés ; - l'API publique reste inchangée.
Le test d'intégration runtime conserve son assertion directe sur un événement tracing::error! de target sqlx. Il reste donc le test de non-régression du takeover effectif, au-delà du test unitaire de Targets::would_enable.
Version technique
Ce correctif modifie du Rust. La version workspace devient :
workspace.package.version = "0.1.2-pre.4.fix.3"
et l'en-tête du Cargo.toml racine devient :
# version: 34
Fichiers du delta
Cargo.toml
crates/ksp-logging-lib/src/runtime.rs
crates/ksp-logging-lib/unit_tests/runtime.rs
docs/plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md
deltas/0.1.2/pre.004-fix.003.md
Validations à exécuter
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test --workspace
Aucune dépendance n'est modifiée par ce fix. Après validation propre, la tranche suivante reste :
0.1.2-pre.005 — intégration + concurrence + saturation + audits