qrush 0.6.0

Lightweight Job Queue and Task Scheduler for Rust (Actix + Redis + Cron)
Documentation
// qrush-engine: Separate worker process runtime.
//
// This binary is intentionally focused on:
// - booting worker pools (queues + concurrency)
// - booting delayed-job handler
// - booting cron scheduler
// - graceful shutdown via SIGINT/SIGTERM
//
// Example:
//   qrush-engine --redis redis://127.0.0.1:6379 --queues default:10,critical:25
//
// Notes:
// - Jobs must be registered via qrush::registry::register_job(...) *before* jobs are produced.
// - This binary starts workers/scheduler based on QueueConfig::initialize(...).
// - Users should create their own binary that registers jobs and calls QueueConfig::initialize()

use clap::Parser;
use tracing_subscriber::EnvFilter;

use qrush::engine::{run_engine, parse_queues};

#[derive(Parser, Debug)]
#[command(name = "qrush-engine", version, about = "Separate worker process runtime for QRush")]
struct Args {
    /// Redis connection URL (also supports env QRUSH_ENGINE_REDIS_URL / REDIS_URL)
    #[arg(long, env = "QRUSH_ENGINE_REDIS_URL", default_value = "redis://127.0.0.1:6379")]
    redis: String,

    /// Queue list, optionally with concurrency and priority:
    ///   default:10
    ///   critical:25:0
    #[arg(long, default_value = "default:10")]
    queues: String,

    /// Grace period before exit after shutdown signal
    #[arg(long, default_value_t = 5)]
    shutdown_grace_secs: u64,
}


#[tokio::main(flavor = "multi_thread")]
async fn main() -> anyhow::Result<()> {
    // Load .env if present
    match dotenvy::dotenv() {
        Ok(path) => println!("Loaded .env from: {}", path.display()),
        Err(_) => println!("⚠️  No .env file found, using environment variables"),
    }

    // Tracing (respects RUST_LOG)
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .init();

    let args = Args::parse();

    // Support REDIS_URL if user didn't set QRUSH_ENGINE_REDIS_URL explicitly.
    let redis_url = std::env::var("QRUSH_ENGINE_REDIS_URL")
        .or_else(|_| std::env::var("REDIS_URL"))
        .unwrap_or_else(|_| args.redis.clone());

    let queues = parse_queues(&args.queues);

    // Note: Jobs must be registered before calling run_engine()
    // Users should create their own binary that registers jobs and calls run_engine()
    run_engine(redis_url, queues, args.shutdown_grace_secs).await
}