radicle_ci_broker

Module timeoutcmd

Source
Expand description

Run a command (an external program) as a sub-process, capturing its output in real time, with a maximum duration.

This is meant for the CI broker to run a CI adapter and process the single-line messages the adapter writes to its standard output, as well as capture stderr output, which the adapter uses for logging. If the adapter runs for too long, it gets terminated.

Note that if the Command that is created to run the command invokes a shell, the shell must exec the command it runs, or in some other way make sure the processes the shell launches get terminated when the shell process ends. Otherwise the time out management here does not work reliably.

The child can be given some data via its stdin.

This module is not entirely generic, as it assumes textual output with lines, instead of arbitrary byte strings.

§Example

let mut cmd = Command::new("bash");
cmd.arg("-c").arg("exec cat"); // Note exec!

let mut to = TimeoutCommand::new(Duration::from_secs(10));
to.feed_stdin(b"hello, world\n");
let running = to.spawn(cmd)?;

// Capture stdout output. We ignore stderr output.
let stdout = running.stdout();
let mut captured = vec![];
while let Some(line) = stdout.line() {
    captured.push(line);
}

// Wait for child process to terminate.
let tor = running.wait()?;
assert_eq!(tor.status().code(), Some(0));
assert_eq!(captured, ["hello, world\n"]);

Structs§

Enums§