use chainmq::{
Job, JobContext, JobOptions, Priority, Queue, QueueOptions, Result, async_trait,
serde_json::json, start_web_ui_simple,
};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct EmailJob {
to: String,
subject: String,
body: String,
}
#[async_trait]
impl Job for EmailJob {
async fn perform(&self, ctx: &JobContext) -> Result<()> {
println!(
"[worker] (example perform) to='{}' subject='{}'",
self.to, self.subject
);
ctx.set_response(json!({
"simulated": true,
"to": self.to,
"subject": self.subject,
}));
Ok(())
}
fn name() -> &'static str {
"EmailJob"
}
fn queue_name() -> &'static str {
"emails"
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::try_init().ok();
println!("[enqueue] Preparing QueueOptions and connecting to Redis...");
let redis_url = "redis://localhost:6370".to_string();
let options = QueueOptions {
redis_url: redis_url.clone(),
..Default::default()
};
let queue = Queue::new(options).await?;
let queue_name = EmailJob::queue_name();
println!(
"[enqueue] Connected to Redis and initialized queue '{}'.",
queue_name
);
let job = EmailJob {
to: "user@example.com".into(),
subject: "Welcome!".into(),
body: "Thanks for signing up".into(),
};
println!("[enqueue] Enqueuing simple EmailJob...");
let job_id = queue.enqueue(job).await?;
println!("[enqueue] Enqueued EmailJob with id={}", job_id);
let urgent = EmailJob {
to: "user@example.com".into(),
subject: "Urgent".into(),
body: "Please read".into(),
};
let response = json!({
"status": "sent",
"to": &urgent.to,
"subject": &urgent.subject,
});
let opts = JobOptions {
delay_secs: Some(60),
priority: Priority::High,
attempts: 5,
..Default::default()
};
println!("[enqueue] Enqueuing delayed/high-priority EmailJob (delay=60s, attempts=5)...");
let job_id2 = queue.enqueue_with_options(urgent, opts).await?;
println!(
"[enqueue] Enqueued delayed EmailJob with id={} — done.",
job_id2
);
let _ = queue
.complete_job(&job_id2, queue_name, Some(response))
.await?;
println!("\n[enqueue] Jobs have been enqueued!");
let ui_queue = Queue::new(QueueOptions {
redis_url: redis_url.clone(),
..Default::default()
})
.await?;
start_web_ui_simple(ui_queue).await?;
Ok(())
}