Crate async_cache

source ·
Expand description

AsyncCache is a cache system that automatically updates and deletes entries using async fetchers.

§Usage

To use AsyncCache, you need to implement the Fetcher trait for the type you want to cache. Then you can use the Options struct to configure the cache and create an instance of AsyncCache.

use async_cache::{AsyncCache, Fetcher, Options};
use faststr::FastStr;
use std::time::Duration;

#[derive(Clone)]
struct MyValue(u32);

#[derive(Clone)]
struct MyFetcher;

impl Fetcher<MyValue> for MyFetcher {
    type Error = anyhow::Error;

    //// The implementation of fetch function should return the value associated with a key, or an error if it fails.
    async fn fetch(&self, key: FastStr) -> Result<MyValue, Self::Error> {
        // Your implementation here
        Ok(MyValue(100))
    }
}

let mut cache =
    Options::new(Duration::from_secs(10), MyFetcher).with_expire(Some(Duration::from_secs(10)))
        .build();

// Now you can use the cache to get and set values
let key = FastStr::from("key");
let val = cache.get_or_set(key.clone(), MyValue(50));

assert_eq!(val, MyValue(50));

let other_val = cache.get(key).await.unwrap();

assert_eq!(other_val, MyValue(50));

§Design

AsyncCache uses async-singleflight to reduce redundant load on underlying fetcher, requests from different future tasks with the same key will only trigger a single fetcher call.

It also provides a few channels to notify the client of the cache when the cache is updated or there was an error with a fetch.

AsyncCache is thread-safe and can be cloned and shared across tasks.

§Example

use async_cache::{AsyncCache, Options};
use faststr::FastStr;
use std::time::Duration;

#[tokio::main]
async fn main() {
    let interval = Duration::from_millis(100);

    let options = Options::new(interval, GitHubFetcher::new())
        .with_expire(Some(Duration::from_secs(30)));

    let cache = options.build();

    let key = FastStr::from("your key");

    match cache.get(key).await {
        Some(v) => println!("value: {}", v),
        None => println!("first fetch failed"),
    }

    tokio::time::delay_for(Duration::from_secs(5)).await;

    match cache.get(key).await {
        Some(v) => println!("value: {}", v),
        None => println!("fetch data failed"),
    }
}

Structs§

Traits§