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§
Sourcefn refresh(&mut self) -> Pin<Box<dyn Future<Output = Result<(), E>> + '_>>
fn refresh(&mut self) -> Pin<Box<dyn Future<Output = Result<(), E>> + '_>>
Refresh cache immediately and update last update time if refresh success.
Sourcefn get(&self) -> Result<&T, TimeoutError>
fn get(&self) -> Result<&T, TimeoutError>
Read current cached value or return Error if cache is already expired.
Sourcefn get_or_refresh<'a>(
&'a mut self,
) -> Pin<Box<dyn Future<Output = Result<&'a T, E>> + 'a>>where
T: 'a,
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.
Sourcefn time_remain(&self) -> Duration
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.