use std::sync::Arc;
use std::time::{Duration, Instant};
use supermachine::Image;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let snap = format!(
"{}/.local/supermachine-snapshots/nginx_1v",
std::env::var("HOME")?
);
let image = Image::from_snapshot(&snap)?;
let pool = Arc::new(
image
.pool()
.min(0)
.max(8)
.idle_timeout(Duration::from_secs(2))
.build()?,
);
println!("=== initial state (min=0, lazy): {:?} ===", pool.stats());
println!("=== burst: 5 simultaneous acquires ===");
let t0 = Instant::now();
let handles: Vec<_> = (0..5)
.map(|i| {
let pool = Arc::clone(&pool);
std::thread::spawn(move || {
let t_local = Instant::now();
let vm = pool.acquire().unwrap();
let t_acq = t_local.elapsed();
std::thread::sleep(Duration::from_millis(50));
drop(vm);
println!(" worker {i} acquired in {t_acq:?}");
})
})
.collect();
for h in handles {
h.join().unwrap();
}
println!(
" burst total: {:?}, stats={:?}",
t0.elapsed(),
pool.stats()
);
println!("=== wait 3s for idle eviction (timeout=2s) ===");
std::thread::sleep(Duration::from_secs(3));
println!(" stats after eviction: {:?}", pool.stats());
println!("=== single acquire after eviction (cold path) ===");
let t0 = Instant::now();
let _vm = pool.acquire()?;
println!(" acquire: {:?} stats={:?}", t0.elapsed(), pool.stats());
Ok(())
}