Réponses concises, sans verbiage. Code efficace avant tout. Commentaires et documentation en français, avec les accents. Les schémas se font en Mermaid — jamais de diagrammes ASCII.
AsyncJsonlQueue : écriture d'un fichier JSONL depuis un thread dédié. Les appelants
déposent une valeur Serialize dans une file bornée ; un unique thread worker sérialise
directement dans un BufWriter de 64 Kio et traite les tâches par lots.
flowchart LR
subgraph Appelants["Threads appelants"]
T1[write(valeur)]
T2[sync(timeout)]
T3[stop() / Drop]
end
CH["crossbeam bounded<br/>CHANNEL_CAPACITY = 16384"]
subgraph Worker["Thread AsyncJsonlWorker"]
R[recv bloquant<br/>puis try_recv en rafale]
S[serialize_into<br/>via effacement de type]
BW[BufWriter 64 Kio]
end
F[(fichier .jsonl<br/>ouvert en append)]
T1 -- JsonlTask::Write --> CH
T2 -- JsonlTask::Sync --> CH
T3 -- JsonlTask::Stop --> CH
CH --> R --> S --> BW --> F
BW -. flush sur Sync<br/>ou buffer plein .-> F
stateDiagram-v2
[*] --> Cree : new(chemin)
Cree --> Demarre : start()
Demarre --> Pret : le worker a ouvert le fichier<br/>(wait_for_ready)
Pret --> Pret : write() / sync()
Pret --> Arrete : stop() ou Drop
Arrete --> [*] : Sync puis Stop puis join puis flush final
writeprend la valeur par déplacement, pas par référence : la sérialisation a lieu dans le worker, jamais chez l'appelant. C'est tout l'intérêt du dessin.- Le flush n'a lieu que sur
Syncou quand leBufWriterdéborde. Sans appel àsync(), des données peuvent rester en mémoire tampon indéfiniment sur un flux peu actif — c'est volontaire, mais cela signifie que la durabilité passe parsync(). stop()envoieSyncpuisStop, dans cet ordre : la file doit être vidée avant que le worker ne sorte de sa boucle.Dropappellestop(): ne jamais laisser une instance fuir si les données comptent.- La file est bornée :
writebloque quand elle est pleine, ce qui protège de l'OOM au prix d'une contre-pression sur l'appelant.
cargo build
cargo test
cargo clippy --all-targets
cargo fmt