use std::sync::Arc;
use std::time::Duration;
use cronoq_core::{SubmitError, TaskId, TaskStatus};
#[derive(Clone, Debug, PartialEq, thiserror::Error)]
pub enum TaskError {
#[error("{message}")]
Retryable {
message: Arc<str>,
retry_after: Option<Duration>,
},
#[error("{message}")]
Permanent {
message: Arc<str>,
},
#[error("cancelled")]
Cancelled,
}
impl TaskError {
pub fn retryable(message: impl Into<Arc<str>>) -> Self {
TaskError::Retryable {
message: message.into(),
retry_after: None,
}
}
pub fn retry_after(message: impl Into<Arc<str>>, after: Duration) -> Self {
TaskError::Retryable {
message: message.into(),
retry_after: Some(after),
}
}
pub fn permanent(message: impl Into<Arc<str>>) -> Self {
TaskError::Permanent {
message: message.into(),
}
}
pub fn from_err(e: impl std::fmt::Display) -> Self {
TaskError::retryable(e.to_string())
}
}
#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum TaskFailure {
#[error("task ended as {status}: {message}")]
Ended {
status: TaskStatus,
message: Arc<str>,
},
#[error("task {id} succeeded, but its output is no longer available")]
OutputUnavailable {
id: TaskId,
},
#[error("scheduler shut down")]
Shutdown,
}
impl TaskFailure {
pub fn status(&self) -> Option<TaskStatus> {
match self {
TaskFailure::Ended { status, .. } => Some(*status),
TaskFailure::OutputUnavailable { .. } => Some(TaskStatus::Succeeded),
TaskFailure::Shutdown => None,
}
}
}
#[derive(Clone, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error(transparent)]
Submit(#[from] SubmitError),
#[error("scheduler is shut down")]
Shutdown,
#[error("configuration error: {0}")]
Config(String),
#[error("store error: {0}")]
Store(#[from] StoreError),
#[error("internal error: {0}")]
Internal(String),
}
#[derive(Clone, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum StoreError {
#[error("fenced: leadership lost")]
Fenced,
#[error("store unavailable: {0}")]
Unavailable(String),
#[error("{0}")]
Other(String),
}
impl StoreError {
pub fn is_transient(&self) -> bool {
matches!(self, StoreError::Unavailable(_))
}
}
#[derive(Clone, Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ScaleError {
#[error("capacity is managed externally")]
External,
#[error("{0}")]
Other(String),
}