Add exact resumable object source streaming
This commit is contained in:
parent
5b43b6c660
commit
0ad79c597f
1 changed files with 1482 additions and 1 deletions
83
crates/remora-object-source/src/error.rs
Normal file
83
crates/remora-object-source/src/error.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
use remora_stream::{StreamError, StreamSide};
|
||||
use remora_target::TargetError;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
|
||||
pub enum ObjectSourceError {
|
||||
#[error("object source request is invalid")]
|
||||
InvalidRequest,
|
||||
#[error("object source access is denied")]
|
||||
SourceAuthorization,
|
||||
#[error("destination access is denied")]
|
||||
DestinationAuthorization,
|
||||
#[error("object source was not found")]
|
||||
SourceNotFound,
|
||||
#[error("object source changed")]
|
||||
SourceChanged,
|
||||
#[error("destination resume state changed")]
|
||||
DestinationChanged,
|
||||
#[error("object source is temporarily unavailable")]
|
||||
TransientSource,
|
||||
#[error("destination is temporarily unavailable")]
|
||||
TransientDestination,
|
||||
#[error("object source adapter failed")]
|
||||
Internal,
|
||||
}
|
||||
|
||||
impl ObjectSourceError {
|
||||
#[must_use]
|
||||
pub fn into_stream_error(self) -> StreamError {
|
||||
match self {
|
||||
Self::SourceAuthorization => StreamError::Authorization {
|
||||
side: StreamSide::Source,
|
||||
},
|
||||
Self::DestinationAuthorization => StreamError::Authorization {
|
||||
side: StreamSide::Target,
|
||||
},
|
||||
Self::SourceNotFound => StreamError::SourceNotFound,
|
||||
Self::SourceChanged => StreamError::SourceChanged,
|
||||
Self::TransientSource => StreamError::transient_source("object source unavailable"),
|
||||
Self::TransientDestination => StreamError::transient_target("destination unavailable"),
|
||||
Self::DestinationChanged => {
|
||||
StreamError::internal("destination resume proof is no longer reusable")
|
||||
}
|
||||
Self::InvalidRequest | Self::Internal => {
|
||||
StreamError::internal("object source contract violation")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_open_error(error: opendal::Error) -> ObjectSourceError {
|
||||
use opendal::ErrorKind;
|
||||
|
||||
match error.kind() {
|
||||
ErrorKind::NotFound => ObjectSourceError::SourceNotFound,
|
||||
ErrorKind::PermissionDenied => ObjectSourceError::SourceAuthorization,
|
||||
ErrorKind::ConditionNotMatch | ErrorKind::RangeNotSatisfied => {
|
||||
ObjectSourceError::SourceChanged
|
||||
}
|
||||
ErrorKind::RateLimited => ObjectSourceError::TransientSource,
|
||||
ErrorKind::Unsupported | ErrorKind::ConfigInvalid => ObjectSourceError::InvalidRequest,
|
||||
_ => ObjectSourceError::TransientSource,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_resume_error(error: opendal::Error) -> ObjectSourceError {
|
||||
match map_open_error(error) {
|
||||
ObjectSourceError::SourceNotFound => ObjectSourceError::SourceChanged,
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn map_destination_error(error: TargetError) -> ObjectSourceError {
|
||||
match error {
|
||||
TargetError::Authorization => ObjectSourceError::DestinationAuthorization,
|
||||
TargetError::NotFound | TargetError::AlreadyExists | TargetError::Integrity(_) => {
|
||||
ObjectSourceError::DestinationChanged
|
||||
}
|
||||
TargetError::Capacity | TargetError::Transient(_) => {
|
||||
ObjectSourceError::TransientDestination
|
||||
}
|
||||
TargetError::Validation(_) | TargetError::Internal(_) => ObjectSourceError::Internal,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue