use super::{SegmentId, TaskId};
use crate::compressor::{ConfigError, EncodeError};
use std::io;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ParallelConfigError {
#[error("invalid parallel segment size: {bytes}")]
InvalidSegmentSize {
bytes: usize,
},
#[error("invalid parallel task count: {count}")]
InvalidTaskCount {
count: usize,
},
#[error("invalid encoder configuration: {0}")]
Encoder(#[from] ConfigError),
#[error("parallel compression currently requires a standard Brotli window")]
UnsupportedParallelWindow,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ParallelEncodeError {
#[error("parallel batch failed: {0}")]
BatchFailed(#[source] std::sync::Arc<ParallelEncodeError>),
#[error("invalid parallel configuration: {0}")]
Config(#[from] ParallelConfigError),
#[error("parallel size calculation overflowed")]
SizeOverflow,
#[error("parallel allocation failed: {0}")]
Allocation(#[from] std::collections::TryReserveError),
#[error("parallel memory staging bound exceeds configured limit")]
MemoryStagingLimit,
#[error("parallel worker memory estimate exceeds configured limit")]
WorkerMemoryLimit,
#[error("source metadata failed: {0}")]
SourceMetadata(#[source] io::Error),
#[error("source changed during compression")]
SourceChanged,
#[error("source read failed for {task:?}, {segment:?}: {source}")]
SourceRead {
task: TaskId,
segment: SegmentId,
#[source]
source: io::Error,
},
#[error("encoding failed for {task:?}, {segment:?}: {source}")]
Encode {
task: TaskId,
segment: SegmentId,
#[source]
source: EncodeError,
},
#[error("staging failed for {task:?}: {source}")]
Staging {
task: TaskId,
#[source]
source: io::Error,
},
#[error("parallel task {task:?} was abandoned")]
TaskAbandoned {
task: TaskId,
},
#[error("parallel task {task:?} panicked")]
TaskPanicked {
task: TaskId,
},
#[error("parallel batch was cancelled")]
Cancelled,
#[error("parallel tasks were already taken")]
TasksAlreadyTaken,
#[error("parallel tasks are not ready")]
NotReady,
#[error("parallel fragment invariant failed: {0}")]
FragmentInvariant(&'static str),
#[error("assembly failed after {bytes_written} bytes: {source}")]
AssemblyIo {
bytes_written: u64,
#[source]
source: io::Error,
},
}
#[derive(Debug)]
pub struct ParallelFinishError<W> {
pub writer: W,
pub error: ParallelEncodeError,
pub bytes_written: u64,
}
impl<W> std::fmt::Display for ParallelFinishError<W> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.error.fmt(f)
}
}
impl<W: std::fmt::Debug> std::error::Error for ParallelFinishError<W> {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(&self.error)
}
}