use genswap::GenSwap;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
#[derive(Debug, Clone)]
struct Config {
feature_flags: Vec<String>,
rate_limit: u32,
timeout_ms: u64,
}
fn main() {
println!("=== GenSwap Example ===\n");
let config = Arc::new(GenSwap::new(Config {
feature_flags: vec!["feature_a".into()],
rate_limit: 100,
timeout_ms: 1000,
}));
println!("Initial config:");
println!(" Generation: {}", config.generation());
println!(" Rate limit: {}\n", config.load_full().rate_limit);
let handles: Vec<_> = (0..4)
.map(|id| {
let config = Arc::clone(&config);
thread::spawn(move || {
let mut reader = config.reader();
let mut reads = 0;
let mut refreshes = 0;
for _ in 0..1000 {
let cfg = reader.get();
reads += 1;
if cfg.rate_limit > 0 && cfg.timeout_ms > 0 {
}
if reader.is_stale() {
refreshes += 1;
}
thread::sleep(Duration::from_micros(100));
}
println!(
"Thread {}: {} reads, {} cache refreshes ({:.2}% hit rate)",
id,
reads,
refreshes,
100.0 * (reads - refreshes) as f64 / reads as f64
);
})
})
.collect();
let producer_config = Arc::clone(&config);
let producer = thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
println!("\nUpdating config (generation 1)...");
producer_config.update(Config {
feature_flags: vec!["feature_a".into(), "feature_b".into()],
rate_limit: 200,
timeout_ms: 1000,
});
thread::sleep(Duration::from_millis(30));
println!("Updating config (generation 2)...");
producer_config.update(Config {
feature_flags: vec!["feature_a".into(), "feature_b".into(), "feature_c".into()],
rate_limit: 300,
timeout_ms: 2000,
});
thread::sleep(Duration::from_millis(30));
println!("Updating config (generation 3)...\n");
producer_config.update(Config {
feature_flags: vec!["feature_a".into(), "feature_b".into()],
rate_limit: 250,
timeout_ms: 1500,
});
});
producer.join().unwrap();
for handle in handles {
handle.join().unwrap();
}
println!("\nFinal config:");
println!(" Generation: {}", config.generation());
println!(" Rate limit: {}", config.load_full().rate_limit);
println!(" Features: {:?}", config.load_full().feature_flags);
println!("\n=== Performance Benefits ===");
println!("Each reader thread performed ~1000 reads with only 3-4 cache refreshes.");
println!("Cache hit rate: >99%");
println!("\nWithout caching, each read would require:");
println!(" - Arc::load_full() -> atomic refcount increment");
println!(" - Drop on return -> atomic refcount decrement");
println!("\nWith GenSwap:");
println!(" - Cache hit: single atomic load (generation check) + return reference");
println!(" - Cache miss: reload + update cached Arc");
println!("\nResult: ~10-100x faster reads in read-heavy workloads!");
}