fix(posts): ensure rebuild invalidates tag posts cache
This commit is contained in:
parent
c03093fc8b
commit
1092fbb3ce
@ -1,7 +1,7 @@
|
|||||||
//! 删除文章接口。
|
//! 删除文章接口。
|
||||||
//!
|
//!
|
||||||
//! 采用软删除方式,将 posts.deleted_at 设置为当前时间,
|
//! 采用软删除方式,将 posts.deleted_at 设置为当前时间,
|
||||||
//! 同时清空所有文章相关缓存。
|
//! 并按影响范围失效相关缓存。
|
||||||
//! Dioxus server function,注册在 `/api` 路径下。
|
//! Dioxus server function,注册在 `/api` 路径下。
|
||||||
//! 仅在 `feature = "server"` 启用的服务端构建中执行删除与缓存失效。
|
//! 仅在 `feature = "server"` 启用的服务端构建中执行删除与缓存失效。
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ use crate::db::pool::get_conn;
|
|||||||
/// 删除指定文章。
|
/// 删除指定文章。
|
||||||
///
|
///
|
||||||
/// 仅 admin 可调用;通过设置 deleted_at 实现软删除,
|
/// 仅 admin 可调用;通过设置 deleted_at 实现软删除,
|
||||||
/// 成功后清空全部文章缓存。
|
/// 成功后按影响范围失效文章列表、标签云、统计、slug 及相关标签文章缓存。
|
||||||
#[server(DeletePost, "/api")]
|
#[server(DeletePost, "/api")]
|
||||||
pub async fn delete_post(post_id: i32) -> Result<CreatePostResponse, ServerFnError> {
|
pub async fn delete_post(post_id: i32) -> Result<CreatePostResponse, ServerFnError> {
|
||||||
let _user = get_current_admin_user().await?;
|
let _user = get_current_admin_user().await?;
|
||||||
|
|||||||
@ -34,14 +34,14 @@ pub async fn rebuild_content_html(rebuild_all: bool) -> Result<RebuildResult, Se
|
|||||||
{
|
{
|
||||||
let client = get_conn().await.map_err(AppError::db_conn)?;
|
let client = get_conn().await.map_err(AppError::db_conn)?;
|
||||||
|
|
||||||
// 根据参数构造 WHERE 条件,限制单次处理数量;同时查询 slug 用于精准失效缓存。
|
// 根据参数构造 WHERE 条件,限制单次处理数量。
|
||||||
let query = if rebuild_all {
|
let query = if rebuild_all {
|
||||||
format!(
|
format!(
|
||||||
"SELECT id, slug, content_md FROM posts WHERE deleted_at IS NULL ORDER BY id LIMIT {REBUILD_BATCH_LIMIT}"
|
"SELECT id, content_md FROM posts WHERE deleted_at IS NULL ORDER BY id LIMIT {REBUILD_BATCH_LIMIT}"
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"SELECT id, slug, content_md FROM posts WHERE deleted_at IS NULL AND content_html IS NULL ORDER BY id LIMIT {REBUILD_BATCH_LIMIT}"
|
"SELECT id, content_md FROM posts WHERE deleted_at IS NULL AND content_html IS NULL ORDER BY id LIMIT {REBUILD_BATCH_LIMIT}"
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,12 +50,10 @@ pub async fn rebuild_content_html(rebuild_all: bool) -> Result<RebuildResult, Se
|
|||||||
let mut rebuilt: u64 = 0;
|
let mut rebuilt: u64 = 0;
|
||||||
let mut failed: u64 = 0;
|
let mut failed: u64 = 0;
|
||||||
let mut errors: Vec<String> = Vec::new();
|
let mut errors: Vec<String> = Vec::new();
|
||||||
let mut rebuilt_slugs: Vec<String> = Vec::with_capacity(rows.len());
|
|
||||||
|
|
||||||
for row in &rows {
|
for row in &rows {
|
||||||
let id: i32 = row.get(0);
|
let id: i32 = row.get(0);
|
||||||
let slug: String = row.get(1);
|
let content_md: String = row.get(1);
|
||||||
let content_md: String = row.get(2);
|
|
||||||
|
|
||||||
// 捕获 Markdown 渲染 panic,避免单条记录导致整批失败。
|
// 捕获 Markdown 渲染 panic,避免单条记录导致整批失败。
|
||||||
let rendered = match std::panic::catch_unwind(|| {
|
let rendered = match std::panic::catch_unwind(|| {
|
||||||
@ -95,7 +93,6 @@ pub async fn rebuild_content_html(rebuild_all: bool) -> Result<RebuildResult, Se
|
|||||||
{
|
{
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
rebuilt += 1;
|
rebuilt += 1;
|
||||||
rebuilt_slugs.push(slug);
|
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
failed += 1;
|
failed += 1;
|
||||||
@ -106,14 +103,10 @@ pub async fn rebuild_content_html(rebuild_all: bool) -> Result<RebuildResult, Se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只要有文章被更新,就按影响范围失效缓存:列表、标签云、统计,以及每篇被重建文章的 slug 缓存。
|
// 重建会修改 word_count / reading_time 等列表项字段,批量影响列表、标签云、
|
||||||
|
// 标签文章及单篇缓存;这里使用全量失效作为务实的回退策略。
|
||||||
if rebuilt > 0 {
|
if rebuilt > 0 {
|
||||||
crate::cache::invalidate_post_lists();
|
crate::cache::invalidate_all_post_caches();
|
||||||
crate::cache::invalidate_all_tags();
|
|
||||||
crate::cache::invalidate_post_stats();
|
|
||||||
for slug in &rebuilt_slugs {
|
|
||||||
crate::cache::invalidate_post_by_slug(slug).await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(RebuildResult {
|
Ok(RebuildResult {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user