ppoppo-infra 0.1.0

Backend-agnostic infrastructure traits for caching, queuing, and messaging
Documentation
//! Backend-agnostic job queue trait.

use async_trait::async_trait;

use crate::Result;
use crate::types::{Job, JobStatus, Priority, QueueStats};

/// Reliable job queue with retry and priority support.
///
/// Uses `serde_json::Value` for payloads to maintain dyn-compatibility.
/// See [`JobQueueExt`](crate::JobQueueExt) for typed convenience methods.
#[async_trait]
pub trait JobQueue: Send + Sync {
    /// Push a job to the queue. Returns the generated job ID.
    async fn push(
        &self,
        queue_name: &str,
        payload: &serde_json::Value,
        priority: Priority,
    ) -> Result<String>;

    /// Push a job with full options. Returns the generated job ID.
    async fn push_with_options(
        &self,
        queue_name: &str,
        payload: &serde_json::Value,
        priority: Priority,
        delay_seconds: i32,
        max_attempts: i32,
    ) -> Result<String>;

    /// Push multiple jobs atomically. Returns list of generated job IDs.
    async fn push_batch(
        &self,
        queue_name: &str,
        jobs: &[(serde_json::Value, Priority)],
    ) -> Result<Vec<String>>;

    /// Pop the next available job from the queue.
    async fn pop(
        &self,
        queue_name: &str,
        lock_duration_seconds: i32,
    ) -> Result<Option<Job>>;

    /// Mark a job as completed.
    ///
    /// `queue_name` is required so partitioned backends can prune to a single partition.
    async fn complete(&self, queue_name: &str, job_id: &str) -> Result<()>;

    /// Mark a job as failed. Returns true if the job will be retried.
    ///
    /// `queue_name` is required so partitioned backends can prune to a single partition.
    async fn fail(&self, queue_name: &str, job_id: &str, error_message: &str) -> Result<bool>;

    /// Extend the lock duration for a long-running job.
    ///
    /// `queue_name` is required so partitioned backends can prune to a single partition.
    async fn heartbeat(&self, queue_name: &str, job_id: &str, extend_seconds: i32) -> Result<()>;

    /// Get job status and details.
    ///
    /// `queue_name` is required so partitioned backends can prune to a single partition.
    async fn get_status(
        &self,
        queue_name: &str,
        job_id: &str,
    ) -> Result<Option<(JobStatus, i32, Option<String>)>>;

    /// Get queue statistics.
    async fn stats(&self, queue_name: &str) -> Result<QueueStats>;

    /// Cancel a pending job. Returns true if job was cancelled.
    ///
    /// `queue_name` is required so partitioned backends can prune to a single partition.
    async fn cancel(&self, queue_name: &str, job_id: &str) -> Result<bool>;

    // cleanup()은 trait에 포함하지 않는다. Cache와 동일한 이유.
    // PgJobQueue::cleanup(retention_days) 참조.
}