pub struct BatchExecutor { /* private fields */ }Expand description
High-performance batch processor for HEDL files.
Orchestrates parallel or serial processing based on configuration and workload. Provides progress tracking and comprehensive error collection.
§Thread Safety
BatchExecutor is thread-safe and can be shared across threads via Arc.
§Examples
use hedl_cli::batch::{BatchExecutor, BatchConfig, ValidationOperation};
use std::path::PathBuf;
let processor = BatchExecutor::new(BatchConfig {
parallel_threshold: 5,
verbose: true,
..Default::default()
});
let files: Vec<PathBuf> = vec![
"file1.hedl".into(),
"file2.hedl".into(),
];
let results = processor.process(
&files,
ValidationOperation { strict: false },
true,
)?;
if results.has_failures() {
eprintln!("Some files failed validation");
for failure in results.failures() {
eprintln!(" - {}: {:?}", failure.path.display(), failure.result);
}
}Implementations§
Source§impl BatchExecutor
impl BatchExecutor
Sourcepub fn new(config: BatchConfig) -> Self
pub fn new(config: BatchConfig) -> Self
Create a new batch processor with the given configuration.
Sourcepub fn default_config() -> Self
pub fn default_config() -> Self
Create a batch processor with default configuration.
Sourcepub fn process<O>(
&self,
files: &[PathBuf],
operation: O,
show_progress: bool,
) -> Result<BatchResults<O::Output>, CliError>where
O: BatchOperation,
pub fn process<O>(
&self,
files: &[PathBuf],
operation: O,
show_progress: bool,
) -> Result<BatchResults<O::Output>, CliError>where
O: BatchOperation,
Process multiple files with the given operation.
Automatically selects parallel or serial processing based on configuration and file count. Provides progress reporting and collects all results.
§Arguments
files- Slice of file paths to processoperation- The operation to perform on each fileshow_progress- Whether to show progress updates
§Returns
Ok(BatchResults)- Successfully processed all files (individual failures collected in results)Err(CliError::ThreadPoolError)- Failed to create thread pool with requested configuration
§Thread Pool Selection
The method uses different thread pool strategies based on configuration:
- Serial Processing: If
files.len() < parallel_threshold, processes serially (no thread pool) - Local Thread Pool: If
max_threadsisSome(n), creates isolated pool withnthreads - Global Thread Pool: If
max_threadsisNone, uses Rayon’s global pool
§Error Handling
Thread pool creation can fail if:
max_threadsis 0 (invalid configuration)- System cannot allocate thread resources
- Thread stack allocation fails
Individual file processing errors are collected in BatchResults, not returned as errors.
§Performance
- Serial processing for small batches to avoid thread pool overhead
- Local thread pool: ~0.5-1ms creation overhead, ~2-8MB per thread
- Global thread pool: zero overhead
- Lock-free progress tracking using atomic counters
§Examples
use hedl_cli::batch::{BatchExecutor, BatchConfig, FormatOperation};
use hedl_cli::error::CliError;
use std::path::PathBuf;
let processor = BatchExecutor::new(BatchConfig {
max_threads: Some(4),
..Default::default()
});
let files = vec![PathBuf::from("a.hedl"), PathBuf::from("b.hedl")];
match processor.process(
&files,
FormatOperation {
check: false,
ditto: true,
with_counts: false,
},
true,
) {
Ok(results) => {
println!("Formatted {} files", results.success_count());
if results.has_failures() {
// Handle individual file failures
}
}
Err(CliError::ThreadPoolError { message, requested_threads }) => {
eprintln!("Failed to create thread pool: {}", message);
}
Err(e) => {
eprintln!("Unexpected error: {}", e);
}
}Sourcepub fn process_streaming<O>(
&self,
files: &[PathBuf],
operation: O,
show_progress: bool,
) -> Result<BatchResults<O::Output>, CliError>where
O: StreamingBatchOperation,
pub fn process_streaming<O>(
&self,
files: &[PathBuf],
operation: O,
show_progress: bool,
) -> Result<BatchResults<O::Output>, CliError>where
O: StreamingBatchOperation,
Process files using streaming operations for memory efficiency.
This method uses the streaming parser from hedl-stream to process files
with constant memory usage regardless of file size. Ideal for:
- Files larger than 100MB
- Memory-constrained environments
- Processing thousands of files
§Arguments
files- Slice of file paths to processoperation- The streaming operation to performshow_progress- Whether to show progress updates
§Returns
Ok(BatchResults)- Always succeeds and collects all individual resultsErr(CliError)- Only on catastrophic failures
§Memory Usage
Peak memory = buffer_size (8KB) × num_threads + ID tracking set
§Examples
use hedl_cli::batch::{BatchExecutor, StreamingValidationOperation, BatchConfig};
use std::path::PathBuf;
let processor = BatchExecutor::default_config();
let files = vec![PathBuf::from("large-file.hedl")];
let operation = StreamingValidationOperation { strict: false };
let results = processor.process_streaming(&files, operation, true)?;
println!("Processed {} files with constant memory", results.success_count());Sourcepub fn process_auto<O, SO>(
&self,
files: &[PathBuf],
standard_op: O,
streaming_op: SO,
show_progress: bool,
) -> Result<BatchResults<O::Output>, CliError>
pub fn process_auto<O, SO>( &self, files: &[PathBuf], standard_op: O, streaming_op: SO, show_progress: bool, ) -> Result<BatchResults<O::Output>, CliError>
Automatically choose between standard and streaming based on file size.
Files larger than 100MB use streaming mode for memory efficiency, while smaller files use standard mode for better performance.
§Arguments
files- Slice of file paths to processstandard_op- Standard operation for small filesstreaming_op- Streaming operation for large filesshow_progress- Whether to show progress updates
§Returns
Ok(BatchResults)- Combined results from both modesErr(CliError)- On catastrophic failures
§Examples
use hedl_cli::batch::{BatchExecutor, ValidationOperation, StreamingValidationOperation};
use std::path::PathBuf;
let processor = BatchExecutor::default_config();
let files = vec![
PathBuf::from("small.hedl"),
PathBuf::from("large-200mb.hedl"),
];
let results = processor.process_auto(
&files,
ValidationOperation { strict: false },
StreamingValidationOperation { strict: false },
true,
)?;
println!("Processed {} files", results.results.len());Trait Implementations§
Source§impl Clone for BatchExecutor
impl Clone for BatchExecutor
Source§fn clone(&self) -> BatchExecutor
fn clone(&self) -> BatchExecutor
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for BatchExecutor
impl RefUnwindSafe for BatchExecutor
impl Send for BatchExecutor
impl Sync for BatchExecutor
impl Unpin for BatchExecutor
impl UnwindSafe for BatchExecutor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more