rustvello_redis/
client_data_store.rs1use std::sync::Arc;
2
3use async_trait::async_trait;
4use redis::AsyncCommands;
5
6use rustvello_core::client_data_store::ClientDataStore;
7use rustvello_core::error::RustvelloResult;
8
9use crate::connection::{redis_err, scan_keys, RedisPool};
10
11#[non_exhaustive]
15pub struct RedisClientDataStore {
16 pool: Arc<RedisPool>,
17 key_prefix: String,
18}
19
20impl RedisClientDataStore {
21 pub fn new(pool: Arc<RedisPool>) -> Self {
22 let p = pool.prefix();
23 Self {
24 key_prefix: format!("{p}cds:"),
25 pool,
26 }
27 }
28}
29
30#[async_trait]
31impl ClientDataStore for RedisClientDataStore {
32 async fn store(&self, key: &str, value: &str) -> RustvelloResult<()> {
33 let mut conn = self.pool.conn().await?;
34 let rkey = format!("{}{}", self.key_prefix, key);
35 conn.set::<_, _, ()>(&rkey, value).await.map_err(redis_err)
36 }
37
38 async fn retrieve(&self, key: &str) -> RustvelloResult<String> {
39 let mut conn = self.pool.conn().await?;
40 let rkey = format!("{}{}", self.key_prefix, key);
41 let val: Option<String> = conn.get(&rkey).await.map_err(redis_err)?;
42 val.ok_or_else(|| {
43 rustvello_core::error::RustvelloError::state_backend(format!(
44 "CDS key not found: {}",
45 key
46 ))
47 })
48 }
49
50 async fn purge(&self) -> RustvelloResult<()> {
51 let mut conn = self.pool.conn().await?;
52 let keys = scan_keys(&mut conn, &format!("{}*", self.key_prefix)).await?;
53 if !keys.is_empty() {
54 conn.del::<_, ()>(keys).await.map_err(redis_err)?;
55 }
56 Ok(())
57 }
58}