CachedObject

Trait CachedObject 

Source
pub trait CachedObject<T, E> {
    // Required methods
    fn refresh(&mut self) -> Pin<Box<dyn Future<Output = Result<(), E>> + '_>>;
    fn get(&self) -> Result<&T, TimeoutError>;
    fn get_or_refresh<'a>(
        &'a mut self,
    ) -> Pin<Box<dyn Future<Output = Result<&'a T, E>> + 'a>>
       where T: 'a;
    fn time_remain(&self) -> Duration;
}
Expand description

A trait to provide a type that hides async refresh function. It allows user to use dyn CachedObject as a trait object or use impl CachedObject to allow compile time trait realization.

Note that this trait return Pin<Box<dyn Future>> instead of impl Future because it allows dyn CachedObject to be used in a trait object context.

This will incur some performance overhead because it requires heap allocation.

This behavior is different from Object which return impl Future that may not allocate on heap.

Usage example, static interior mutability with std::sync::LazyLock and std::sync::RwLock to create a global thread safe cached object.

use core::time::Duration;
use generic_cache::{CachedObject, Object};
use std::sync::{LazyLock, RwLock};
use tokio::time::sleep;

static CACHED: LazyLock<RwLock<Box<dyn CachedObject<u16, ()> + Send + Sync>>> = LazyLock::new(|| {
   RwLock::new(Box::new(Object::new(std::time::Duration::from_secs(1), 100, async || {Ok::<u16, ()>(200)})))
});
assert_eq!((&*CACHED).read().unwrap().get().unwrap(), &100u16);
sleep(Duration::from_secs(2)).await;
assert!((&*CACHED).read().unwrap().get().is_err(), "Cache should be expired");
assert_eq!((&*CACHED).write().unwrap().get_or_refresh().await.unwrap(), &200u16, "Cache should be refreshed to 200");

Until https://github.com/rust-lang/rust/issues/63065 is resolved, we cannot use impl CachedObject in a static binding so dyn CachedObject is currently the only solution available.

Required Methods§

Source

fn refresh(&mut self) -> Pin<Box<dyn Future<Output = Result<(), E>> + '_>>

Refresh cache immediately and update last update time if refresh success.

Source

fn get(&self) -> Result<&T, TimeoutError>

Read current cached value or return Error if cache is already expired.

Source

fn get_or_refresh<'a>( &'a mut self, ) -> Pin<Box<dyn Future<Output = Result<&'a T, E>> + 'a>>
where T: 'a,

Read current cached value or refresh the value if it is already expired then return the new value.

Source

fn time_remain(&self) -> Duration

Get time remain that the cache still valid. In other word, time remain before it return TimeoutError on Object::get function.

Implementors§

Source§

impl<T, F, E> CachedObject<T, E> for Object<T, F, E>
where F: AsyncFnMut() -> Result<T, E>,