Files
appks/immediate/dedup.rs
T
2026-06-07 11:30:56 +08:00

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(())
}
}