Skip to main content

output_stream

Function output_stream 

Source
pub fn output_stream<'a, R, I>(
    commands: I,
    concurrency: usize,
    runner: &'a R,
) -> impl Stream<Item = (usize, Result<ProcessResult<String>>)> + Send + 'a
where R: ProcessRunner + ?Sized, I: IntoIterator<Item = Command> + 'a,
Expand description

Run every command in commands with at most concurrency live at once, yielding each result — an (input index, Result<ProcessResult<String>>) pair — the moment that command finishes. This is the streaming sibling of output_all: the same bounded fan-out and the same per-command error semantics (an Err is a spawn/I/O failure; a non-zero exit is an Ok(ProcessResult); the fan-out never short-circuits), but presented as a Stream over completions instead of a single Vec at the end.

Key differences from output_all:

  • Completion order, not input order. Items arrive as commands finish, so a fast command never blocks behind a slow one. Each item carries the command’s input index (its position in commands), so you can still map a result back to its source; if you need the input-order Vec, use output_all (which is this stream collected by index).
  • Partial results survive cancellation. Every result already yielded is owned by the consumer, so dropping the stream mid-fan-out keeps them — unlike output_all, whose Vec materializes only at the very end (its “no partial results” limitation).

concurrency is clamped to at least 1. An empty commands yields an empty stream (immediately None).

Cancellation / teardown. Dropping the stream drops the in-flight command futures — with an own-group runner (JobRunner) that kills every still-live process tree (no orphans), matching output_all; with a shared-group runner (&ProcessGroup) they live until the group is torn down. Commands still waiting for a concurrency slot are dropped without ever being spawned — a queued command runs nothing until it is scheduled, so cancelling the fan-out cancels them for free.

The returned stream borrows runner for 'a; consume it with StreamExt (while let Some((i, res)) = stream.next().await).