yggdrasil/src/tasks/post_purge.rs

75 lines
2.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 回收站自动清理后台任务。
//!
//! 仅在 `server` feature 启用时编译,每天运行一次。
//! 每次执行前读取 settings 表:若自动清理关闭则跳过,否则按保留天数物理删除过期文章。
use std::time::Duration;
use tokio::time::interval;
use crate::db::pool::get_conn;
use crate::models::settings::TrashSettings;
/// 启动回收站自动清理循环,每天触发一次。
///
/// 每次读取最新配置:若 `trash_auto_purge_enabled` 关闭则 no-op
/// 否则删除 `deleted_at < NOW() - retention_days` 的文章。
/// 任何错误只记录日志,不中断循环。
pub async fn run_purge() {
let mut ticker = interval(Duration::from_secs(86400));
loop {
ticker.tick().await;
match get_conn().await {
Ok(client) => {
match purge_expired(&client).await {
Ok(n) => {
if n > 0 {
tracing::info!("Post auto-purge: removed {} expired trashed posts", n);
}
}
Err(e) => tracing::error!("Post auto-purge error: {:?}", e),
}
}
Err(e) => tracing::error!("Failed to get DB connection for post purge: {:?}", e),
}
}
}
/// 读取配置并删除过期回收站文章,返回删除行数。
///
/// 抽取为独立函数便于单元测试(虽需 DB但逻辑集中
async fn purge_expired(client: &tokio_postgres::Client) -> Result<u64, tokio_postgres::Error> {
// 读取配置,缺键时回退默认值。
let enabled: bool = client
.query_opt(
"SELECT value FROM settings WHERE key = 'trash_auto_purge_enabled'",
&[],
)
.await?
.and_then(|r| r.get::<_, String>("value").parse().ok())
.unwrap_or(false);
if !enabled {
return Ok(0);
}
let days: i32 = client
.query_opt(
"SELECT value FROM settings WHERE key = 'trash_retention_days'",
&[],
)
.await?
.and_then(|r| r.get::<_, String>("value").parse().ok())
.unwrap_or(30);
let days = TrashSettings::clamp_retention(days);
let n = client
.execute(
"DELETE FROM posts WHERE deleted_at IS NOT NULL AND deleted_at < NOW() - make_interval(days => $1)",
&[&days],
)
.await?;
Ok(n)
}