use backbone_jobs::{JobScheduler, JobBuilder, JobSchedulerBuilder};
use backbone_jobs::job_storage::InMemoryJobStorage;
use backbone_jobs::job_executor::MockQueueService;
use chrono::Utc;
use serde_json::json;
use std::sync::Arc;
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
let storage = Arc::new(InMemoryJobStorage::new());
let queue_service = Arc::new(MockQueueService::new());
let scheduler = Arc::new(
JobSchedulerBuilder::new()
.storage(storage)
.build()
.await?,
);
scheduler.start().await?;
println!("🚀 Job Scheduler started successfully!");
let frequent_job = JobBuilder::new()
.id("frequent_job".to_string())
.name("Frequent Demo Job")
.description("Runs every minute for demonstration")
.cron("*/1 * * * *") .queue("demo_queue".to_string())
.payload(json!({
"type": "demo",
"message": "This job runs every minute",
"timestamp": Utc::now().to_rfc3339()
}))
.build()?;
scheduler.schedule_job(frequent_job).await?;
println!("✅ Scheduled frequent job (every minute)");
let cleanup_job = JobBuilder::new()
.id("cleanup_job".to_string())
.name("Data Cleanup")
.description("Clean up old demo data")
.cron("*/5 * * * *") .queue("cleanup_queue".to_string())
.payload(json!({
"type": "cleanup",
"target": "demo_data",
"older_than_minutes": 60
}))
.build()?;
scheduler.schedule_job(cleanup_job).await?;
println!("✅ Scheduled cleanup job (every 5 minutes)");
let health_job = JobBuilder::new()
.id("health_check".to_string())
.name("System Health Check")
.description("Check system health and status")
.cron("*/2 * * * *") .queue("health_queue".to_string())
.payload(json!({
"type": "health_check",
"services": ["database", "queue", "cache"]
}))
.build()?;
scheduler.schedule_job(health_job).await?;
println!("✅ Scheduled health check job (every 2 minutes)");
let report_job = JobBuilder::new()
.id("report_job".to_string())
.name("Demo Report Generation")
.description("Generate demo analytics report")
.cron("*/10 * * * *") .queue("reports_queue".to_string())
.payload(json!({
"type": "report",
"report_type": "demo_analytics",
"format": "json"
}))
.build()?;
scheduler.schedule_job(report_job).await?;
println!("✅ Scheduled report job (every 10 minutes)");
let stats = scheduler.get_statistics().await?;
println!("\n📊 Initial Scheduler Statistics:");
println!(" Total jobs: {}", stats.total_jobs);
println!(" Active workers: {}", stats.active_workers);
println!(" Queued jobs: {}", stats.queued_jobs);
let jobs = scheduler.list_jobs().await?;
println!("\n📋 Scheduled Jobs:");
for job in jobs {
println!(" - {} ({})", job.name, job.status);
println!(" Cron: {}", job.cron_expression);
println!(" Queue: {}", job.queue);
println!(" Next run: {}", job.next_run_time.unwrap_or_default());
}
println!("\n⏰ Scheduler is now running... Press Ctrl+C to stop");
println!("💡 Jobs will be executed according to their cron schedules");
let scheduler_clone = Arc::clone(&scheduler);
tokio::spawn(async move {
let scheduler = scheduler_clone;
let mut interval = tokio::time::interval(Duration::from_secs(10));
loop {
interval.tick().await;
match scheduler.get_statistics().await {
Ok(stats) => {
println!("📈 Live Stats - Total: {}, Workers: {}, Queued: {}",
stats.total_jobs, stats.active_workers, stats.queued_jobs);
}
Err(e) => {
eprintln!("❌ Error getting statistics: {}", e);
}
}
}
});
println!("⏱️ Running for 5 minutes demonstration...");
sleep(Duration::from_secs(300)).await;
println!("\n🛑 Shutting down scheduler...");
scheduler.stop().await?;
println!("✅ Scheduler shutdown complete");
Ok(())
}