Moka Cache TTL In Memory
Cache expensive computations with moka in Rust, combining TTL expiry with maximum size, entry metrics, and async loading.
Code
use moka::future::Cache;
use std::time::Duration;
#[derive(Debug, Clone)]
struct ExchangeRates {
base: String,
rates: Vec<(String, f64)>,
}
async fn fetch_rates(base: &str) -> ExchangeRates {
// 模拟外部 API 的网络往返
tokio::time::sleep(Duration::from_millis(50)).await;
ExchangeRates {
base: base.into(),
rates: vec![
("usd".into(), 1.0),
("eur".into(), 0.92),
("jpy".into(), 149.6),
],
}
}
fn build_cache() -> Cache<String, ExchangeRates> {
Cache::builder()
.time_to_live(Duration::from_secs(30)) // 条目级 TTL
.max_capacity(10_000)
.weigher(|_key, value: &ExchangeRates| -> u32 {
value.rates.len() as u32
})
.build()
}
#[tokio::main]
async fn main() {
let cache = build_cache();
// 手动模式:先查后填
if let Some(hit) = cache.get("base-eur").await {
println!("cache hit: {:?} entries", hit.rates.len());
} else {
let fresh = fetch_rates("eur").await;
cache.insert("base-eur".into(), fresh).await;
println!("cache miss: loaded and inserted");
}
// 自动加载模式:未命中时原子执行加载器
let auto = Cache::builder()
.time_to_live(Duration::from_secs(60))
.build();
let rates = auto
.try_get_with(
"base-jpy",
fetch_rates("jpy"),
)
.await
.expect("loader should not fail");
println!("auto-loaded {} rates for {}", rates.rates.len(), rates.base);
println!("entry count: {}", auto.entry_count());
println!("cached weight: {}", auto.weighted_size());
}Report a problem with this exampleOpens a pre-filled issue on GitHub.