Expand description
A generic cached object which provide user two possible usage options.
- Use Object::get() until it return TimeoutError then manually call Object::refresh() function.
- Use Object::get_or_refresh() which will automatically refresh the value when it is expired.
The different between the two is that the Object::get() is more flexible because it only borrow
the cache value while the Object::get_or_refresh() will required a borrow mut of Object itself because it
might need to change the cached value. However, the auto refresh is convenient because user doesn’t
need to handle TimeoutError when cache is expired.
Both usage options still need to handle refresh_fn
error if any.
§Example
- Verify two cached call to get value back to back to check if it is actually the same value.
use generic_cache::{CachedObject, Object};
let cached = Object::new(std::time::Duration::from_secs(1), 100, async || {Ok::<u16, ()>(200)}); // Explicitly define type for Error. Otherwise, compile will fail.
let first = cached.get().unwrap();
let second = cached.get().unwrap();
assert_eq!(*first, 100, "Expect {} to equals {}", *first, 0);
assert_eq!(first, second, "Expect {} to equals {}", first, second);
- Check for expired then refresh the cache
use core::time;
use std::thread::sleep;
use generic_cache::Object;
let mut cached = Object::new(std::time::Duration::from_millis(100), 100, async || {Ok::<u16, ()>(200)}); // Explicitly define type for Error. Otherwise, compile will fail.
let first = *cached.get().unwrap();
sleep(time::Duration::from_millis(200));
if let Ok(_) = cached.get() {
panic!("Cache should be expired but it is not.")
} else {
cached.refresh().await.unwrap();
}
let second = *cached.get().unwrap();
assert_ne!(first, second, "Expect {} to equals {}", first, second);
- Auto refresh expired cache value
use core::time;
use std::thread::sleep;
use generic_cache::Object;
let mut cached = Object::new(std::time::Duration::from_secs(0), 100, async || {Ok::<u16, ()>(200)}); // Explicitly define type for Error. Otherwise, compile will fail.
let first = *cached.get_or_refresh().await.unwrap();
sleep(time::Duration::from_millis(1));
let second = *cached.get_or_refresh().await.unwrap();
assert_eq!(first, second, "Expect {} to equals {}", first, second);
- No default value when create a cache and auto refresh expired cache value
use core::time;
use std::thread::sleep;
use generic_cache::Object;
let mut cached = Object::new_and_refresh(std::time::Duration::from_secs(1), async || {Ok::<u16, ()>(200)}).await.unwrap(); // Explicitly define type for Error. Otherwise, compile will fail.
let first = *cached.get_or_refresh().await.unwrap();
let second = *cached.get_or_refresh().await.unwrap();
assert_eq!(first, second, "Expect {} to equals {}", first, second);
Structs§
- Object
- Generic cache object which cache an object for given period of time before it return TimeoutError to signal caller to call refresh function before further attempt. The refresh_fn should be async function that return Result of the same type as the cached object. If there’s any error occur inside refresh_fn, it should return Error result back.
- Timeout
Error - The cache is timeout. Object::refresh() need to be called.
Traits§
- Cached
Object - A trait to provide a type that hides async refresh function.
It allows user to use
dyn CachedObject
as a trait object or useimpl CachedObject
to allow compile time trait realization.