eh: attempt to prevent resource leaks
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I28d716bd37d17dd96731c7863b3383416a6a6964
This commit is contained in:
parent
dd3a8a4151
commit
cc5fd676c9
3 changed files with 29 additions and 5 deletions
|
|
@ -2,6 +2,7 @@ use std::{
|
|||
collections::VecDeque,
|
||||
io::{self, Read, Write},
|
||||
process::{Command, ExitStatus, Output, Stdio},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use crate::error::{EhError, Result};
|
||||
|
|
@ -27,6 +28,9 @@ impl LogInterceptor for StdIoInterceptor {
|
|||
/// Default buffer size for reading command output
|
||||
const DEFAULT_BUFFER_SIZE: usize = 4096;
|
||||
|
||||
/// Default timeout for command execution
|
||||
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(300); // 5 minutes
|
||||
|
||||
/// Builder and executor for Nix commands.
|
||||
pub struct NixCommand {
|
||||
subcommand: String,
|
||||
|
|
@ -147,10 +151,19 @@ impl NixCommand {
|
|||
|
||||
let mut out_queue = VecDeque::new();
|
||||
let mut err_queue = VecDeque::new();
|
||||
let start_time = Instant::now();
|
||||
|
||||
loop {
|
||||
let mut did_something = false;
|
||||
|
||||
// Check for timeout
|
||||
if start_time.elapsed() > DEFAULT_TIMEOUT {
|
||||
let _ = child.kill();
|
||||
return Err(EhError::CommandFailed {
|
||||
command: format!("nix {} timed out after 5 minutes", self.subcommand),
|
||||
});
|
||||
}
|
||||
|
||||
match stdout.read(&mut out_buf) {
|
||||
Ok(0) => {},
|
||||
Ok(n) => {
|
||||
|
|
@ -176,6 +189,11 @@ impl NixCommand {
|
|||
if !did_something && child.try_wait()?.is_some() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Prevent busy waiting when no data is available
|
||||
if !did_something {
|
||||
std::thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
}
|
||||
|
||||
let status = child.wait()?;
|
||||
|
|
|
|||
|
|
@ -40,9 +40,15 @@ impl EhError {
|
|||
pub const fn exit_code(&self) -> i32 {
|
||||
match self {
|
||||
Self::ProcessExit { code } => *code,
|
||||
Self::NixCommandFailed(_) => 1,
|
||||
Self::CommandFailed { .. } => 1,
|
||||
_ => 1,
|
||||
Self::NixCommandFailed(_) => 2,
|
||||
Self::CommandFailed { .. } => 3,
|
||||
Self::HashExtractionFailed => 4,
|
||||
Self::NoNixFilesFound => 5,
|
||||
Self::HashFixFailed { .. } => 6,
|
||||
Self::InvalidInput { .. } => 7,
|
||||
Self::Io(_) => 8,
|
||||
Self::Regex(_) => 9,
|
||||
Self::Utf8(_) => 10,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue