use ai_batch_queue::*;
#[allow(dead_code)]
struct SimulatedProcessor;
impl BatchItemHandler<String> for SimulatedProcessor {
async fn process(
&self,
_data: &String,
_resource_key: &str,
_operation: &str,
) -> anyhow::Result<ItemResult> {
Ok(ItemResult::success())
}
}
fn main() {
let queue: BatchQueue<String> = BatchQueue::new();
let items = vec![
("img-1".into(), "small.jpg".into(), SizeBucket::Small),
("img-2".into(), "medium.jpg".into(), SizeBucket::Medium),
("img-3".into(), "large.jpg".into(), SizeBucket::Large),
("img-4".into(), "small2.jpg".into(), SizeBucket::Small),
("img-5".into(), "medium2.jpg".into(), SizeBucket::Medium),
];
let job_id = queue
.enqueue(build_job("llava:13b", "tag", OverwritePolicy::Skip, items))
.unwrap();
queue.mark_running(&job_id).unwrap();
let eta = queue.estimate_remaining_ms(&job_id);
println!("ETA before any data: {:?}", eta);
println!("\nSimulating item completions...");
queue
.update_item(
&job_id,
"img-1",
BatchItemStatus::Completed,
None,
Some(500),
)
.unwrap();
println!(" Completed small image in 500ms");
let eta = queue.estimate_remaining_ms(&job_id);
println!(" ETA for 4 remaining: {:?}ms", eta);
queue
.update_item(
&job_id,
"img-2",
BatchItemStatus::Completed,
None,
Some(1200),
)
.unwrap();
println!(" Completed medium image in 1200ms");
let eta = queue.estimate_remaining_ms(&job_id);
println!(" ETA for 3 remaining: {:?}ms", eta);
queue
.update_item(
&job_id,
"img-3",
BatchItemStatus::Completed,
None,
Some(3000),
)
.unwrap();
println!(" Completed large image in 3000ms");
let eta = queue.estimate_remaining_ms(&job_id);
println!(" ETA for 2 remaining (small + medium): {:?}ms", eta);
println!("\nETA accuracy improves with more data points.");
println!("Estimates are bucketed by (model, operation, image_size).");
assert_eq!(
queue.eta_sample_count("llava:13b", "tag", SizeBucket::Small),
1
);
assert_eq!(
queue.eta_sample_count("llava:13b", "tag", SizeBucket::Medium),
1
);
assert_eq!(
queue.eta_sample_count("llava:13b", "tag", SizeBucket::Large),
1
);
}