use std::time::Duration;
use snerd_rust::file_store::FileStore;
use snerd_rust::queue::SnerdQueue;
use snerd_rust::rate_limiter::RateLimiter;
use snerd_rust::task::RetryableTask;
#[tokio::main]
async fn main() {
let store = FileStore::new(".snerdata_dashboard_demo/tasks/tasks.log").unwrap();
let limiter = RateLimiter::new(&std::path::PathBuf::from("."));
let queue = SnerdQueue::new("dashboard-demo", store, limiter);
let q_progress = queue.clone();
queue
.register_task_handler("progress-task", move |data| {
for i in 1..=5 {
q_progress.yield_progress(
"progress-task-1",
&format!("step {}/5 of {}", i, data),
);
std::thread::sleep(Duration::from_millis(300));
}
Ok(())
})
.await;
queue
.register_task_handler("fail-task", |_data| Err("boom: intentional failure".to_string()))
.await;
let q_cron = queue.clone();
queue
.register_task_handler("cron-ping", move |_data| {
q_cron.yield_progress(
"cron-ping-1",
&format!("cron ping at {}", chrono::Utc::now().to_rfc3339()),
);
Ok(())
})
.await;
queue
.register_task_handler("slow-task", |_data| {
std::thread::sleep(Duration::from_secs(6));
Ok(())
})
.await;
queue.start_processor(Duration::from_secs(1)).await;
queue.start_dashboard(9021);
queue
.enqueue(RetryableTask::new(
"progress-task-1".to_string(),
"progress-task".to_string(),
r#"{"job":"demo"}"#.to_string(),
2, 0.0, None, None, None, None, None, None, None, None,
))
.unwrap();
queue
.enqueue(RetryableTask::new(
"fail-task-1".to_string(),
"fail-task".to_string(),
"{}".to_string(),
1, 0.0001, None, None, None, None, None, None, None, None,
))
.unwrap();
let future = (chrono::Utc::now() + chrono::Duration::hours(1)).to_rfc3339();
queue
.enqueue(RetryableTask::new(
"future-task-1".to_string(),
"progress-task".to_string(),
"{}".to_string(),
1, 0.0, None, None, None, None, Some(future), None, None, None,
))
.unwrap();
queue
.enqueue(RetryableTask::new(
"cron-ping-1".to_string(),
"cron-ping".to_string(),
"{}".to_string(),
2, 0.0, None, None, None, None, None,
Some("*/10 * * * * *".to_string()),
None, None,
))
.unwrap();
queue
.enqueue(RetryableTask::new(
"webhook-task-1".to_string(),
"webhook-task".to_string(),
r#"{"via":"webhook"}"#.to_string(),
2, 0.0, None, None, None, None, None, None,
Some("http://localhost:9010/webhook-ok".to_string()),
None,
))
.unwrap();
queue
.enqueue(RetryableTask::new(
"timeout-task-1".to_string(),
"slow-task".to_string(),
"{}".to_string(),
1, 0.0005, None, None, None, None, None, None, None,
Some(2),
))
.unwrap();
println!("Demo running — dashboard on http://localhost:9021 (Ctrl+C to stop)");
let mut tick = 0u64;
loop {
tokio::time::sleep(Duration::from_secs(3)).await;
tick += 1;
queue.yield_progress(
"heartbeat",
&format!("tick #{} — queue healthy at {}", tick, chrono::Utc::now().to_rfc3339()),
);
}
}