teaql_cache_integration_redis/
lib.rs1use async_trait::async_trait;
2use redis::AsyncCommands;
3use teaql_core::Value;
4use teaql_runtime::DataStore;
5
6#[derive(Clone)]
8pub struct RedisDataStore {
9 client: redis::Client,
10 conn: redis::aio::MultiplexedConnection,
11}
12
13impl RedisDataStore {
14 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 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}