diff --git a/interactive/src/backend/corgi.rs b/interactive/src/backend/corgi.rs index 48b065e7a..7c09c4e3a 100644 --- a/interactive/src/backend/corgi.rs +++ b/interactive/src/backend/corgi.rs @@ -265,13 +265,19 @@ impl Backend for CorgiBackend { } fn inspect<'s>(c: Collection<'s, Time, CC>, label: String) -> Collection<'s, Time, CC> { + use std::fmt::Write; c.inner .unary(Pipeline, "CorgiInspect", move |_, _| { + let mut line = String::new(); move |input, output| { input.for_each(|cap, data| { let mut cont = std::mem::take(data); for ((k, v), t, d) in cont.clone().into_updates() { - eprintln!(" [{label}] (({k:?}, {v:?}), {t:?}, {d})"); + // Format before taking stderr's lock: nested Debug output + // otherwise writes many small fragments while holding it. + line.clear(); + writeln!(&mut line, " [{label}] (({k:?}, {v:?}), {t:?}, {d})").unwrap(); + eprint!("{line}"); } output.session(&cap).give_container(&mut cont); }); diff --git a/interactive/src/backend/vec.rs b/interactive/src/backend/vec.rs index b6e10dd43..eecd62aec 100644 --- a/interactive/src/backend/vec.rs +++ b/interactive/src/backend/vec.rs @@ -173,7 +173,14 @@ impl Backend for VecBackend { ) } fn inspect<'s>(c: Collection<'s, Time, Self::Container>, label: String) -> Collection<'s, Time, Self::Container> { - c.inspect(move |x| eprintln!(" [{}] {:?}", label, x.clone())) + use std::fmt::Write; + let mut line = String::new(); + c.inspect(move |x| { + // Keep formatting outside stderr's lock, and write one complete record. + line.clear(); + writeln!(&mut line, " [{label}] {x:?}").unwrap(); + eprint!("{line}"); + }) } fn leave_dynamic<'s>(c: Collection<'s, Time, Self::Container>, depth: usize) -> Collection<'s, Time, Self::Container> { c.leave_dynamic(depth)