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,
|
collections::VecDeque,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
process::{Command, ExitStatus, Output, Stdio},
|
process::{Command, ExitStatus, Output, Stdio},
|
||||||
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::{EhError, Result};
|
use crate::error::{EhError, Result};
|
||||||
|
|
@ -27,6 +28,9 @@ impl LogInterceptor for StdIoInterceptor {
|
||||||
/// Default buffer size for reading command output
|
/// Default buffer size for reading command output
|
||||||
const DEFAULT_BUFFER_SIZE: usize = 4096;
|
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.
|
/// Builder and executor for Nix commands.
|
||||||
pub struct NixCommand {
|
pub struct NixCommand {
|
||||||
subcommand: String,
|
subcommand: String,
|
||||||
|
|
@ -147,10 +151,19 @@ impl NixCommand {
|
||||||
|
|
||||||
let mut out_queue = VecDeque::new();
|
let mut out_queue = VecDeque::new();
|
||||||
let mut err_queue = VecDeque::new();
|
let mut err_queue = VecDeque::new();
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut did_something = false;
|
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) {
|
match stdout.read(&mut out_buf) {
|
||||||
Ok(0) => {},
|
Ok(0) => {},
|
||||||
Ok(n) => {
|
Ok(n) => {
|
||||||
|
|
@ -176,6 +189,11 @@ impl NixCommand {
|
||||||
if !did_something && child.try_wait()?.is_some() {
|
if !did_something && child.try_wait()?.is_some() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent busy waiting when no data is available
|
||||||
|
if !did_something {
|
||||||
|
std::thread::sleep(Duration::from_millis(10));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let status = child.wait()?;
|
let status = child.wait()?;
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,15 @@ impl EhError {
|
||||||
pub const fn exit_code(&self) -> i32 {
|
pub const fn exit_code(&self) -> i32 {
|
||||||
match self {
|
match self {
|
||||||
Self::ProcessExit { code } => *code,
|
Self::ProcessExit { code } => *code,
|
||||||
Self::NixCommandFailed(_) => 1,
|
Self::NixCommandFailed(_) => 2,
|
||||||
Self::CommandFailed { .. } => 1,
|
Self::CommandFailed { .. } => 3,
|
||||||
_ => 1,
|
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