use std::io::{self, ErrorKind};
use cachet::{Cache, CacheEntry, CacheTier, Error};
use recoverable::{Recovery, RecoveryInfo, RecoveryKind};
use tick::Clock;
#[derive(Clone)]
struct FailingCache;
impl CacheTier<String, i32> for FailingCache {
async fn get(&self, _key: &String) -> Result<Option<CacheEntry<i32>>, Error> {
Err(Error::from_source(io::Error::new(ErrorKind::TimedOut, "connection timed out")).with_recovery(RecoveryInfo::retry()))
}
async fn insert(&self, _key: String, _entry: CacheEntry<i32>) -> Result<(), Error> {
Ok(())
}
async fn invalidate(&self, _key: &String) -> Result<(), Error> {
Ok(())
}
async fn clear(&self) -> Result<(), Error> {
Ok(())
}
}
#[tokio::main]
async fn main() {
let clock = Clock::new_tokio();
let cache = Cache::builder(clock).storage(FailingCache).build();
match cache.get(&"key".to_string()).await {
Ok(Some(entry)) => println!("Got: {}", entry.value()),
Ok(None) => println!("Got: not found"),
Err(e) => {
match e.recovery().kind() {
RecoveryKind::Retry => println!("Error is transient - retrying may help"),
RecoveryKind::Never => println!("Error is permanent - don't retry"),
_ => println!("Unknown recovery strategy"),
}
if let Some(io_err) = e.source_as::<io::Error>() {
println!("Underlying cause: {} ({})", io_err, io_err.kind());
}
}
}
}