use async_trait::async_trait;
use axum::Router;
use futures::future::BoxFuture;
use serde::{Deserialize, Serialize};
use qrush::config::{set_redis_url, QueueConfig};
use qrush::job::Job;
use qrush::queue::enqueue;
use qrush::registry::register_job;
use qrush::routes::axum_route::qrush_metrics_router;
#[derive(Serialize, Deserialize)]
struct NotifyUser {
user_id: String,
message: String,
}
#[async_trait]
impl Job for NotifyUser {
async fn perform(&self) -> anyhow::Result<()> {
println!("Notify {} -> {}", self.user_id, self.message);
Ok(())
}
fn name(&self) -> &'static str {
"NotifyUser"
}
fn queue(&self) -> &'static str {
"default"
}
}
impl NotifyUser {
fn type_name() -> &'static str {
"NotifyUser"
}
fn handler(payload: String) -> BoxFuture<'static, anyhow::Result<Box<dyn Job>>> {
Box::pin(async move {
let job: NotifyUser = serde_json::from_str(&payload)?;
Ok(Box::new(job) as Box<dyn Job>)
})
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let redis_url =
std::env::var("REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
set_redis_url(redis_url.clone())?;
register_job(NotifyUser::type_name(), NotifyUser::handler);
let queues = vec![QueueConfig::new("default", 5, 0)];
QueueConfig::initialize(redis_url, queues).await?;
let _ = enqueue(NotifyUser {
user_id: "123".into(),
message: "Hello from the Axum example".into(),
})
.await;
let app = Router::new().nest("/qrush", qrush_metrics_router());
let port = std::env::var("PORT").unwrap_or_else(|_| "8080".to_string());
println!("QRush dashboard: http://127.0.0.1:{port}/qrush/metrics");
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await?;
axum::serve(listener, app).await?;
Ok(())
}