Files
noworkers/crates/noworkers/examples/with_limit.rs
kjuulh f6d07134f9
All checks were successful
continuous-integration/drone/push Build is passing
feat: add docs and examples
Signed-off-by: kjuulh <contact@kjuulh.io>
2025-08-08 22:43:45 +02:00

86 lines
2.8 KiB
Rust

//! Concurrency limiting with noworkers.
//!
//! This example shows how to limit the number of concurrent tasks
//! to prevent resource exhaustion and control parallelism.
use noworkers::Workers;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Instant;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
println!("Concurrency Limiting Example");
println!("============================\n");
// Track concurrent task count
let concurrent_count = Arc::new(AtomicUsize::new(0));
let max_seen = Arc::new(AtomicUsize::new(0));
let mut workers = Workers::new();
// Limit to 3 concurrent tasks
let limit = 3;
workers.with_limit(limit);
println!("Concurrency limit set to: {}\n", limit);
let start = Instant::now();
// Spawn 10 tasks, but only 3 will run at a time
for i in 0..10 {
let count = concurrent_count.clone();
let max = max_seen.clone();
workers
.add(move |_cancel| async move {
// Increment concurrent count
let current = count.fetch_add(1, Ordering::SeqCst) + 1;
// Track maximum concurrency
let mut max_val = max.load(Ordering::SeqCst);
while current > max_val {
match max.compare_exchange_weak(
max_val,
current,
Ordering::SeqCst,
Ordering::SeqCst,
) {
Ok(_) => break,
Err(x) => max_val = x,
}
}
println!(
"[{:>3}ms] Task {:>2} started (concurrent: {})",
start.elapsed().as_millis(),
i,
current
);
// Simulate work
tokio::time::sleep(tokio::time::Duration::from_millis(200)).await;
// Decrement concurrent count
let remaining = count.fetch_sub(1, Ordering::SeqCst) - 1;
println!(
"[{:>3}ms] Task {:>2} finished (remaining: {})",
start.elapsed().as_millis(),
i,
remaining
);
Ok(())
})
.await?;
}
workers.wait().await?;
println!("\n========== Summary ==========");
println!("Total time: {}ms", start.elapsed().as_millis());
println!("Max concurrent tasks: {}", max_seen.load(Ordering::SeqCst));
println!("Expected batches: {} (10 tasks / 3 limit)", (10 + limit - 1) / limit);
println!("Expected time: ~{}ms (4 batches * 200ms)", ((10 + limit - 1) / limit) * 200);
Ok(())
}