From 2c08659563e82f57f99f9fe7a4213572321ea7bb Mon Sep 17 00:00:00 2001 From: Mick Grove Date: Thu, 30 Apr 2026 00:32:49 -0700 Subject: [PATCH] copilot fixes --- .../kingfisher-rules/data/rules/airbrake.yml | 3 --- src/reporter/json_format.rs | 20 +++++++++++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/crates/kingfisher-rules/data/rules/airbrake.yml b/crates/kingfisher-rules/data/rules/airbrake.yml index e755027..8275640 100644 --- a/crates/kingfisher-rules/data/rules/airbrake.yml +++ b/crates/kingfisher-rules/data/rules/airbrake.yml @@ -33,9 +33,6 @@ rules: - status: - 200 type: StatusMatch - - words: - - '"id"' - type: WordMatch - words: - '"type":"Unauthorized"' type: WordMatch diff --git a/src/reporter/json_format.rs b/src/reporter/json_format.rs index 8843fdc..2c60f41 100644 --- a/src/reporter/json_format.rs +++ b/src/reporter/json_format.rs @@ -12,8 +12,24 @@ impl DetailsReporter { // scan path: one envelope per repo) concatenate into valid // JSONL that `kingfisher view` can parse. Pipe through `jq .` // for human-readable pretty output. - serde_json::to_writer(&mut writer, &envelope)?; - writeln!(writer)?; + // + // Serialize into a single buffer and write it atomically while + // holding stdout's reentrant lock. The parallel scan path + // emits one envelope per repo from many rayon threads, each + // with its own `BufWriter`. Without this lock, the + // multiple `write()` calls produced by `serde_json::to_writer` + // and the eventual BufWriter flush can interleave across + // threads and corrupt JSONL lines. Stdout's lock is reentrant + // so internal `Stdout::write` calls during the flush don't + // deadlock with the explicit lock acquired here. For non-stdout + // writers (e.g. file output) the stdout lock is harmless extra + // contention. + let mut buf = Vec::with_capacity(8 * 1024); + serde_json::to_writer(&mut buf, &envelope)?; + buf.push(b'\n'); + let _stdout_lock = std::io::stdout().lock(); + writer.write_all(&buf)?; + writer.flush()?; } Ok(()) }