Skip to main content

doido_cache/
multi.rs

1//! Batch cache operations (Rails `read_multi`/`write_multi`/`fetch_multi`).
2
3use crate::store::CacheStore;
4use doido_core::Result;
5use serde_json::Value;
6use std::collections::BTreeMap;
7
8/// Read several keys at once; only present keys appear in the result.
9pub async fn read_multi(store: &dyn CacheStore, keys: &[&str]) -> Result<BTreeMap<String, Value>> {
10    let mut out = BTreeMap::new();
11    for &key in keys {
12        if let Some(value) = store.get(key).await? {
13            out.insert(key.to_string(), value);
14        }
15    }
16    Ok(out)
17}
18
19/// Write several key/value pairs at once.
20pub async fn write_multi(
21    store: &dyn CacheStore,
22    entries: &[(&str, Value)],
23    ttl_secs: Option<u64>,
24) -> Result<()> {
25    for (key, value) in entries {
26        store.set(key, value.clone(), ttl_secs).await?;
27    }
28    Ok(())
29}
30
31/// Read several keys, computing (and caching) any misses with `render`.
32pub async fn fetch_multi(
33    store: &dyn CacheStore,
34    keys: &[&str],
35    ttl_secs: Option<u64>,
36    render: impl Fn(&str) -> Value,
37) -> Result<BTreeMap<String, Value>> {
38    let mut out = BTreeMap::new();
39    for &key in keys {
40        let value = match store.get(key).await? {
41            Some(value) => value,
42            None => {
43                let computed = render(key);
44                store.set(key, computed.clone(), ttl_secs).await?;
45                computed
46            }
47        };
48        out.insert(key.to_string(), value);
49    }
50    Ok(out)
51}