//! # Redis connection management use crate::app_config::AppConfig; use redis::Commands; use serde::de::DeserializeOwned; use std::cell::RefCell; use std::time::Duration; thread_local! { static REDIS_CONNECTION: RefCell> = RefCell::new(None); } /// Execute a request on Redis fn execute_request(cb: E) -> anyhow::Result where E: FnOnce(&mut redis::Client) -> anyhow::Result, { // Establish connection if required if REDIS_CONNECTION.with(|i| i.borrow().is_none()) { let conn = redis::Client::open(AppConfig::get().redis_connection_config())?; REDIS_CONNECTION.with(|i| *i.borrow_mut() = Some(conn)) } REDIS_CONNECTION.with(|i| cb(i.borrow_mut().as_mut().unwrap())) } /// Get a value stored on Redis pub async fn get_value(key: &str) -> anyhow::Result> where E: DeserializeOwned, { let value: Option = execute_request(|conn| Ok(conn.get(key)?))?; Ok(match value { None => None, Some(v) => serde_json::from_str(&v)?, }) } /// Set a new value on Redis pub async fn set_value(key: &str, value: &E, lifetime: Duration) -> anyhow::Result<()> where E: serde::Serialize, { let value_str = serde_json::to_string(value)?; execute_request(|conn| Ok(conn.set_ex(key, value_str, lifetime.as_secs() as usize)?))?; Ok(()) } /// Remove a value from Redis pub async fn remove_value(key: &str) -> anyhow::Result<()> { execute_request(|conn| Ok(conn.del(key)?))?; Ok(()) }