Skip to main content

teaql_cache_integration_redis/
lib.rs

1use async_trait::async_trait;
2use redis::AsyncCommands;
3use teaql_core::Value;
4use teaql_runtime::DataStore;
5
6/// A Redis implementation of the DataStore trait for distributed caching
7#[derive(Clone)]
8pub struct RedisDataStore {
9    client: redis::Client,
10    conn: redis::aio::MultiplexedConnection,
11}
12
13impl RedisDataStore {
14    /// Creates a new Redis data store by connecting to the specified URL.
15    /// URL format: redis://[<username>][:<password>@]<hostname>[:port][/<db>]
16    pub async fn new(redis_url: &str) -> Result<Self, redis::RedisError> {
17        let client = redis::Client::open(redis_url)?;
18        let conn = client.get_multiplexed_tokio_connection().await?;
19        Ok(Self { client, conn })
20    }
21
22    /// Provides access to the underlying redis client if needed
23    pub fn client(&self) -> &redis::Client {
24        &self.client
25    }
26}
27
28#[async_trait]
29impl DataStore for RedisDataStore {
30    async fn get(&self, key: &str) -> Option<Value> {
31        let mut conn = self.conn.clone();
32        let result: redis::RedisResult<Option<String>> = conn.get(key).await;
33
34        if let Ok(Some(json_str)) = result
35            && let Ok(json_value) = serde_json::from_str::<serde_json::Value>(&json_str)
36        {
37            return Some(Value::from(json_value));
38        }
39        None
40    }
41
42    async fn put(&self, key: &str, value: Value, timeout_seconds: Option<u64>) {
43        let mut conn = self.conn.clone();
44        let json_str = match serde_json::to_string(&value.to_json_value()) {
45            Ok(s) => s,
46            Err(_) => return,
47        };
48
49        match timeout_seconds {
50            Some(secs) => {
51                let _: redis::RedisResult<()> = conn.set_ex(key, json_str, secs).await;
52            }
53            None => {
54                let _: redis::RedisResult<()> = conn.set(key, json_str).await;
55            }
56        }
57    }
58
59    async fn remove(&self, key: &str) {
60        let mut conn = self.conn.clone();
61        let _: redis::RedisResult<()> = conn.del(key).await;
62    }
63}