feat: init
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::cache::redis::AppRedis;
|
||||
use crate::error::{AppError, AppResult};
|
||||
use ::redis::Cmd;
|
||||
|
||||
use super::redis_keys::*;
|
||||
|
||||
pub struct ReconnectManager {
|
||||
redis: AppRedis,
|
||||
}
|
||||
|
||||
impl ReconnectManager {
|
||||
pub fn new(redis: AppRedis) -> Self {
|
||||
Self { redis }
|
||||
}
|
||||
|
||||
pub fn save_read_position(&self, user_id: Uuid, channel_id: Uuid, seq: i64) -> AppResult<()> {
|
||||
let key = format!("{WS_RECONNECT_PREFIX}{user_id}:{channel_id}");
|
||||
let mut conn = self.redis.get_connection()?;
|
||||
Cmd::new()
|
||||
.arg("SETEX")
|
||||
.arg(&key)
|
||||
.arg(WS_RECONNECT_STATE_TTL_SECS)
|
||||
.arg(seq.to_string())
|
||||
.query::<()>(&mut *conn.inner_mut())
|
||||
.map_err(AppError::Redis)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn save_read_positions(
|
||||
&self,
|
||||
user_id: Uuid,
|
||||
positions: &HashMap<Uuid, i64>,
|
||||
) -> AppResult<()> {
|
||||
let mut conn = self.redis.get_connection()?;
|
||||
for (channel_id, seq) in positions {
|
||||
let key = format!("{WS_RECONNECT_PREFIX}{user_id}:{channel_id}");
|
||||
Cmd::new()
|
||||
.arg("SETEX")
|
||||
.arg(&key)
|
||||
.arg(WS_RECONNECT_STATE_TTL_SECS)
|
||||
.arg(seq.to_string())
|
||||
.query::<()>(&mut *conn.inner_mut())
|
||||
.map_err(AppError::Redis)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_last_seq(&self, user_id: Uuid, channel_id: Uuid) -> AppResult<Option<i64>> {
|
||||
let key = format!("{WS_RECONNECT_PREFIX}{user_id}:{channel_id}");
|
||||
let mut conn = self.redis.get_connection()?;
|
||||
let val: Option<String> = Cmd::new()
|
||||
.arg("GET")
|
||||
.arg(&key)
|
||||
.query(&mut *conn.inner_mut())
|
||||
.map_err(AppError::Redis)?;
|
||||
Ok(val.and_then(|v| v.parse().ok()))
|
||||
}
|
||||
|
||||
pub fn get_all_positions(&self, user_id: Uuid) -> AppResult<HashMap<Uuid, i64>> {
|
||||
let pattern = format!("{WS_RECONNECT_PREFIX}{user_id}:*");
|
||||
let mut conn = self.redis.get_connection()?;
|
||||
let keys: Vec<String> = Cmd::new()
|
||||
.arg("KEYS")
|
||||
.arg(&pattern)
|
||||
.query(&mut *conn.inner_mut())
|
||||
.map_err(AppError::Redis)?;
|
||||
let mut result = HashMap::new();
|
||||
let prefix_len = format!("{WS_RECONNECT_PREFIX}{user_id}:").len();
|
||||
for key in &keys {
|
||||
if let Some(channel_str) = key.get(prefix_len..)
|
||||
&& let Ok(channel_id) = channel_str.parse::<Uuid>()
|
||||
{
|
||||
let val: Option<String> = Cmd::new()
|
||||
.arg("GET")
|
||||
.arg(key)
|
||||
.query(&mut *conn.inner_mut())
|
||||
.map_err(AppError::Redis)?;
|
||||
if let Some(v) = val
|
||||
&& let Ok(seq) = v.parse::<i64>()
|
||||
{
|
||||
result.insert(channel_id, seq);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn cleanup_channel(&self, user_id: Uuid, channel_id: Uuid) -> AppResult<()> {
|
||||
let key = format!("{WS_RECONNECT_PREFIX}{user_id}:{channel_id}");
|
||||
let mut conn = self.redis.get_connection()?;
|
||||
let _ = Cmd::new()
|
||||
.arg("DEL")
|
||||
.arg(&key)
|
||||
.query::<()>(&mut *conn.inner_mut());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user