1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
use log::error; use r2d2_redis::{r2d2::Pool, RedisConnectionManager}; use std::sync::Arc; use std::time::Duration; type ConnectionPool = Arc<Pool<RedisConnectionManager>>; pub use r2d2_redis::redis::Commands; pub fn create_pool(url: &str, size: u32, timeout: u64) -> ConnectionPool { let manager = RedisConnectionManager::new(url).expect("Error creating cache connection manager"); let pool = Pool::builder() .max_size(size) .connection_timeout(Duration::from_secs(timeout)) .build(manager) .expect("Error creating a cache pool"); Arc::new(pool) } #[derive(Debug, Clone)] pub struct Cache { pool: ConnectionPool, expiration_time: u64, } pub(crate) enum Response { Hit(bool), Miss, } impl Cache { pub fn new(pool: ConnectionPool, expiration_time: u64) -> Self { Self { pool, expiration_time, } } pub(crate) fn get(&self, key: &str) -> Response { if let Ok(mut conn) = self.pool.get() { if let Ok(resp) = conn.get(key) { return match resp { Some(1) => Response::Hit(true), Some(_) => Response::Hit(false), None => Response::Miss, }; } } error!("Cache is unavailable"); Response::Miss } pub(crate) fn set(&self, key: &str, value: bool) { if let Ok(mut conn) = self.pool.get() { let result: Result<bool, _> = conn.set_ex(key, value as u8, self.expiration_time as usize); if Ok(true) == result { return; } } error!("Cache is unavailable"); } }