| Crates.io | ferro-queue |
| lib.rs | ferro-queue |
| version | 0.1.71 |
| created_at | 2026-01-16 17:13:16.450707+00 |
| updated_at | 2026-01-17 20:04:31.19896+00 |
| description | Background job queue system for Ferro framework |
| homepage | |
| repository | https://github.com/albertogferrario/ferro |
| max_upload_size | |
| id | 2048979 |
| size | 93,937 |
Background job queue system for the Ferro framework.
Add to your Cargo.toml:
[dependencies]
ferro-queue = "0.1"
Or use it through the main Ferro framework which re-exports all queue types.
use ferro_queue::{Queue, QueueConfig};
// Load configuration from environment
let config = QueueConfig::from_env();
Queue::init(config).await?;
Environment variables:
| Variable | Description | Default |
|---|---|---|
QUEUE_CONNECTION |
"sync" or "redis" | sync |
QUEUE_DEFAULT |
Default queue name | default |
QUEUE_PREFIX |
Redis key prefix | ferro_queue |
QUEUE_BLOCK_TIMEOUT |
Seconds to block waiting for jobs | 5 |
QUEUE_MAX_CONCURRENT |
Max concurrent jobs per worker | 10 |
REDIS_URL |
Full Redis URL (takes precedence) | - |
REDIS_HOST |
Redis host | 127.0.0.1 |
REDIS_PORT |
Redis port | 6379 |
REDIS_PASSWORD |
Redis password | - |
REDIS_DATABASE |
Redis database number | 0 |
use ferro_queue::QueueConfig;
use std::time::Duration;
let config = QueueConfig::new("redis://localhost:6379")
.default_queue("high-priority")
.prefix("myapp")
.max_concurrent_jobs(5)
.block_timeout(Duration::from_secs(10));
use ferro_queue::{Job, Queueable, Error};
use serde::{Deserialize, Serialize};
use async_trait::async_trait;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct SendEmail {
to: String,
subject: String,
body: String,
}
#[async_trait]
impl Job for SendEmail {
async fn handle(&self) -> Result<(), Error> {
// Job logic here
println!("Sending email to {}: {}", self.to, self.subject);
Ok(())
}
fn max_retries(&self) -> u32 {
3
}
fn retry_delay(&self, attempt: u32) -> std::time::Duration {
// Exponential backoff
std::time::Duration::from_secs(2u64.pow(attempt))
}
async fn failed(&self, error: &Error) {
tracing::error!("Email job failed: {:?}", error);
}
}
// Dispatch immediately
SendEmail {
to: "user@example.com".into(),
subject: "Hello".into(),
body: "Welcome!".into(),
}
.dispatch()
.await?;
// Dispatch with delay
SendEmail { /* ... */ }
.delay(std::time::Duration::from_secs(60))
.dispatch()
.await?;
// Dispatch to specific queue
SendEmail { /* ... */ }
.on_queue("emails")
.dispatch()
.await?;
// Combine options
SendEmail { /* ... */ }
.delay(std::time::Duration::from_secs(300))
.on_queue("high-priority")
.dispatch()
.await?;
use ferro_queue::{Worker, WorkerConfig};
// Create worker for default queue
let worker = Worker::new(WorkerConfig::default());
// Register job handlers
worker.register::<SendEmail>();
// Run the worker (blocks until shutdown)
worker.run().await?;
For development, you can use sync mode which processes jobs immediately without Redis:
QUEUE_CONNECTION=sync
Check if sync mode is enabled:
use ferro_queue::QueueConfig;
if QueueConfig::is_sync_mode() {
// Jobs will be processed synchronously
}
Generate a new job with the CLI:
ferro make:job SendWelcomeEmail
This creates src/jobs/send_welcome_email.rs with boilerplate code.
MIT