59 lines
1.7 KiB
Rust
59 lines
1.7 KiB
Rust
use uuid::Uuid;
|
|
|
|
use crate::cache::redis::AppRedis;
|
|
use crate::error::AppResult;
|
|
use ::redis::Cmd;
|
|
|
|
use super::redis_keys::*;
|
|
|
|
pub struct DedupManager {
|
|
redis: AppRedis,
|
|
window_secs: u64,
|
|
}
|
|
|
|
impl DedupManager {
|
|
pub fn new(redis: AppRedis) -> Self {
|
|
Self {
|
|
redis,
|
|
window_secs: WS_DEDUP_WINDOW_SECS,
|
|
}
|
|
}
|
|
|
|
pub fn check_and_mark(&self, message_id: Uuid, channel_id: Uuid) -> AppResult<bool> {
|
|
let key = format!("{WS_DEDUP_PREFIX}{channel_id}:{message_id}");
|
|
let mut conn = self.redis.get_connection()?;
|
|
let result: Option<String> = Cmd::new()
|
|
.arg("SET")
|
|
.arg(&key)
|
|
.arg("1")
|
|
.arg("NX")
|
|
.arg("EX")
|
|
.arg(self.window_secs)
|
|
.query(&mut *conn.inner_mut())
|
|
.map_err(crate::error::AppError::Redis)?;
|
|
Ok(result.is_some())
|
|
}
|
|
|
|
pub fn is_duplicate(&self, message_id: Uuid, channel_id: Uuid) -> AppResult<bool> {
|
|
let key = format!("{WS_DEDUP_PREFIX}{channel_id}:{message_id}");
|
|
let mut conn = self.redis.get_connection()?;
|
|
let exists: bool = Cmd::new()
|
|
.arg("EXISTS")
|
|
.arg(&key)
|
|
.query(&mut *conn.inner_mut())
|
|
.map_err(crate::error::AppError::Redis)?;
|
|
Ok(exists)
|
|
}
|
|
|
|
pub fn clear(&self, message_id: Uuid, channel_id: Uuid) -> AppResult<()> {
|
|
let key = format!("{WS_DEDUP_PREFIX}{channel_id}:{message_id}");
|
|
let mut conn = self.redis.get_connection()?;
|
|
Cmd::new()
|
|
.arg("DEL")
|
|
.arg(&key)
|
|
.query::<()>(&mut *conn.inner_mut())
|
|
.map_err(crate::error::AppError::Redis)?;
|
|
Ok(())
|
|
}
|
|
}
|