Skip to content

Commit ace8e29

Browse files
committed
Optimize read2 streaming
Before, the whole stdout/stderr buffer would be copied unnecessarily after each data chunk was received.
1 parent 71dfcd1 commit ace8e29

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

collector/src/lib.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,27 +177,28 @@ fn run_command_with_output(cmd: &mut Command) -> anyhow::Result<process::Output>
177177
.spawn()
178178
.with_context(|| format!("failed to spawn process for cmd: {:?}", cmd))?;
179179

180-
let mut stdout = Vec::new();
181-
let mut stderr = Vec::new();
182-
let mut stdout_writer = std::io::LineWriter::new(std::io::stdout());
183-
let mut stderr_writer = std::io::LineWriter::new(std::io::stderr());
184-
read2::read2(
180+
let mut stdout_writer = std::io::LineWriter::new(std::io::stdout().lock());
181+
let mut stderr_writer = std::io::LineWriter::new(std::io::stderr().lock());
182+
183+
let mut stdout_written = 0;
184+
let mut stderr_written = 0;
185+
let (stdout, stderr) = read2::read2(
185186
child.stdout.take().unwrap(),
186187
child.stderr.take().unwrap(),
187188
&mut |is_stdout, buffer, _is_done| {
188189
// Send output if trace logging is enabled
189190
if log::log_enabled!(target: "raw_cargo_messages", log::Level::Trace) {
190191
use std::io::Write;
191192
if is_stdout {
192-
stdout_writer.write_all(&buffer[stdout.len()..]).unwrap();
193+
stdout_writer.write_all(&buffer[stdout_written..]).unwrap();
193194
} else {
194-
stderr_writer.write_all(&buffer[stderr.len()..]).unwrap();
195+
stderr_writer.write_all(&buffer[stderr_written..]).unwrap();
195196
}
196197
}
197198
if is_stdout {
198-
stdout = buffer.clone();
199+
stdout_written = buffer.len();
199200
} else {
200-
stderr = buffer.clone();
201+
stderr_written = buffer.len();
201202
}
202203
},
203204
)?;

collector/src/utils/read2.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ mod imp {
3131
use std::os::unix::prelude::*;
3232
use std::process::{ChildStderr, ChildStdout};
3333

34+
/// Returns (stdout, stderr).
3435
pub fn read2(
3536
mut out_pipe: ChildStdout,
3637
mut err_pipe: ChildStderr,
3738
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
38-
) -> io::Result<()> {
39+
) -> io::Result<(Vec<u8>, Vec<u8>)> {
3940
unsafe {
4041
libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
4142
libc::fcntl(err_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
@@ -93,7 +94,7 @@ mod imp {
9394
}
9495
data(true, &mut out, out_done);
9596
}
96-
Ok(())
97+
Ok((out, err))
9798
}
9899
}
99100

@@ -120,7 +121,7 @@ mod imp {
120121
out_pipe: ChildStdout,
121122
err_pipe: ChildStderr,
122123
data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
123-
) -> io::Result<()> {
124+
) -> io::Result<(Vec<u8>, Vec<u8>)> {
124125
let mut out = Vec::new();
125126
let mut err = Vec::new();
126127

@@ -151,7 +152,7 @@ mod imp {
151152
}
152153
}
153154

154-
Ok(())
155+
Ok((out, err))
155156
}
156157
}
157158

0 commit comments

Comments
 (0)