use azoth::AzothDb;
use azoth_scheduler::prelude::*;
use rusqlite::Connection;
use std::sync::Arc;
use std::time::Duration;
struct PrintHandler;
impl TaskHandler for PrintHandler {
fn task_type(&self) -> &str {
"print"
}
fn execute(&self, ctx: &TaskContext, payload: &[u8]) -> Result<TaskEvent> {
let message = String::from_utf8_lossy(payload);
println!(
"[Task {}] Execution #{}: {}",
ctx.task_id, ctx.execution_attempt, message
);
Ok(TaskEvent {
event_type: "message_printed".to_string(),
payload: payload.to_vec(),
})
}
}
struct WorkHandler;
impl TaskHandler for WorkHandler {
fn task_type(&self) -> &str {
"work"
}
fn execute(&self, ctx: &TaskContext, _payload: &[u8]) -> Result<TaskEvent> {
println!(
"[Task {}] Starting work (execution #{})",
ctx.task_id, ctx.execution_attempt
);
std::thread::sleep(Duration::from_millis(500));
println!("[Task {}] Work completed", ctx.task_id);
Ok(TaskEvent {
event_type: "work_completed".to_string(),
payload: serde_json::to_vec(&serde_json::json!({
"task_id": ctx.task_id,
"execution_id": ctx.execution_id,
}))
.unwrap(),
})
}
}
#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter("azoth_scheduler=debug,basic_scheduler=debug")
.init();
println!("=== Azoth Scheduler Example ===\n");
let db = Arc::new(AzothDb::open("./data/scheduler-example")?);
#[allow(clippy::arc_with_non_send_sync)]
let conn = Arc::new(Connection::open("./data/scheduler-example/projection.db")?);
let mut scheduler = Scheduler::builder(db.clone())
.with_task_handler(PrintHandler)
.with_task_handler(WorkHandler)
.with_poll_interval(Duration::from_secs(1))
.with_max_concurrent_tasks(5)
.build(conn)?;
println!("Scheduler created. Scheduling tasks...\n");
scheduler.schedule_task(
ScheduleTaskRequest::builder("welcome")
.task_type("print")
.immediate()
.payload(b"Welcome to Azoth Scheduler!".to_vec())
.build()?,
)?;
scheduler.schedule_task(
ScheduleTaskRequest::builder("heartbeat")
.task_type("print")
.interval(3) .payload(b"Heartbeat...".to_vec())
.build()?,
)?;
scheduler.schedule_task(
ScheduleTaskRequest::builder("background-work")
.task_type("work")
.interval(5) .payload(vec![])
.build()?,
)?;
println!("Tasks scheduled. Running for 30 seconds (for demo)...\n");
tokio::select! {
res = scheduler.run() => {
res?;
}
_ = tokio::time::sleep(Duration::from_secs(30)) => {
println!("\nDemo timeout reached, stopping scheduler...");
scheduler.shutdown();
}
}
println!("Scheduler stopped.");
Ok(())
}