跳到主要内容

📬 Background Jobs & Worker Queues

Long-running operations (PDF report compilation, video transcoding, external API syncs, batch emails) must never run inside HTTP request handlers.

Ferrox provides ferrox-jobs, integrating Apalis and Redis to manage persistent background job queues with automatic worker scaling and retries.


1. Defining a Job

Define your job payload struct implementing apalis::prelude::Job:

use serde::{Deserialize, Serialize};
use apalis::prelude::*;

#[derive(Debug, Deserialize, Serialize)]
pub struct ProcessVideoJob {
pub video_id: String,
pub storage_path: String,
}

impl Job for ProcessVideoJob {
const NAME: &'static str = "ferrox::ProcessVideoJob";
}

2. Worker Processing Function

Write the asynchronous processing logic for the job:

use apalis::prelude::*;

pub async fn process_video_worker(job: ProcessVideoJob, _ctx: JobContext) -> Result<(), apalis::prelude::Error> {
println!("🎬 Worker starting video transcoding for ID: {}", job.video_id);

// Simulate long-running processing
tokio::time::sleep(std::time::Duration::from_secs(5)).await;

println!("✅ Video processing complete!");
Ok(())
}

3. Starting the Background Worker Engine

Launch worker pools during main.rs application startup:

use ferrox_jobs::start_worker;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Start Redis worker pool with 4 concurrent worker threads
let redis_url = "redis://127.0.0.1:6379";
start_worker(redis_url).await?;

println!("⚡ Background Job Engine active!");
Ok(())
}

4. ✅ Best Practices

  • Set up dead-letter queues: Capture failed jobs after max retries so developers can inspect and replay problematic payloads.