use crate::{JobContext, Result};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct JobId(pub Uuid);
impl JobId {
pub fn new() -> Self {
Self(Uuid::new_v4())
}
}
impl std::fmt::Display for JobId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JobLogLine {
pub ts: String,
pub level: String,
pub message: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Priority {
Low = 1,
Normal = 5,
High = 10,
Critical = 20,
}
impl Default for Priority {
fn default() -> Self {
Priority::Normal
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum JobState {
Waiting,
Active,
Completed,
Failed,
Delayed,
Paused,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JobOptions {
#[serde(default)]
pub job_id: Option<JobId>,
pub delay_secs: Option<u64>,
pub priority: Priority,
pub attempts: u32,
pub backoff: crate::backoff::BackoffStrategy,
pub timeout_secs: Option<u64>,
pub rate_limit_key: Option<String>,
}
impl Default for JobOptions {
fn default() -> Self {
Self {
job_id: None,
delay_secs: None,
priority: Priority::Normal,
attempts: 3,
backoff: crate::backoff::BackoffStrategy::Exponential { base: 2, cap: 300 },
timeout_secs: Some(300), rate_limit_key: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JobMetadata {
pub id: JobId,
pub name: String,
pub queue_name: String,
pub payload: serde_json::Value,
pub options: JobOptions,
pub state: JobState,
pub attempts: u32,
pub created_at: DateTime<Utc>,
pub started_at: Option<DateTime<Utc>>,
pub completed_at: Option<DateTime<Utc>>,
pub failed_at: Option<DateTime<Utc>>,
pub last_error: Option<String>,
pub worker_id: Option<String>,
#[serde(default)]
pub response: Option<serde_json::Value>,
}
#[async_trait::async_trait]
pub trait Job: Send + Sync + 'static + serde::de::DeserializeOwned + serde::Serialize {
async fn perform(&self, ctx: &JobContext) -> Result<()>;
fn name() -> &'static str
where
Self: Sized;
fn queue_name() -> &'static str
where
Self: Sized,
{
"default"
}
fn default_options() -> JobOptions
where
Self: Sized,
{
JobOptions::default()
}
}