mod common;
use cacheflight::{CacheFlight, Result};
use common::MemoryCache;
use std::sync::{
Arc,
atomic::{AtomicUsize, Ordering},
};
use std::time::Duration;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<()> {
let cf = CacheFlight::new(MemoryCache::new())
.ttl(Duration::from_millis(200))
.probabilistic_expiry(2.0);
let recomputes = Arc::new(AtomicUsize::new(0));
cf.run("key:flat", {
let recomputes = recomputes.clone();
move || {
let recomputes = recomputes.clone();
async move {
recomputes.fetch_add(1, Ordering::SeqCst);
sleep(Duration::from_millis(30)).await;
Ok(b"flat-value".to_vec())
}
}
})
.await?;
for i in 1..=10 {
let prev = recomputes.load(Ordering::SeqCst);
let result = cf
.run("key:flat", {
let recomputes = recomputes.clone();
move || {
let recomputes = recomputes.clone();
async move {
recomputes.fetch_add(1, Ordering::SeqCst);
sleep(Duration::from_millis(30)).await;
Ok(b"flat-value".to_vec())
}
}
})
.await?;
println!(
"flat-ttl | read {i:>2}: state={:?}, recomputes={prev}",
result.state(),
);
sleep(Duration::from_millis(30)).await;
}
let cf = CacheFlight::new(MemoryCache::new())
.stale_while_revalidate(Duration::from_millis(150), Duration::from_millis(500))
.probabilistic_expiry(2.0);
let recomputes = Arc::new(AtomicUsize::new(0));
cf.run("key:swr", {
let recomputes = recomputes.clone();
move || {
let recomputes = recomputes.clone();
async move {
recomputes.fetch_add(1, Ordering::SeqCst);
sleep(Duration::from_millis(30)).await;
Ok(b"swr-value".to_vec())
}
}
})
.await?;
for i in 1..=15 {
let prev = recomputes.load(Ordering::SeqCst);
let result = cf
.run("key:swr", {
let recomputes = recomputes.clone();
move || {
let recomputes = recomputes.clone();
async move {
recomputes.fetch_add(1, Ordering::SeqCst);
sleep(Duration::from_millis(30)).await;
Ok(b"swr-value".to_vec())
}
}
})
.await?;
println!(
"swr+xfetch | read {i:>2}: state={:?}, recomputes={prev}",
result.state(),
);
sleep(Duration::from_millis(30)).await;
}
println!();
println!("XFetch probabilistically expires entries before their TTL");
println!("based on the observed compute duration and beta parameter.");
println!("The type-state API keeps configuration at compile time:");
println!(" .ttl(d).probabilistic_expiry(beta) => CacheFlight<B, HasFlatExpiry, HasXfetch>");
println!(
" .stale_while_revalidate(f,s).probabilistic_expiry(beta) => CacheFlight<B, HasSwrExpiry, HasXfetch>"
);
Ok(())
}