refactor(posts): use precise cache invalidation in create/update/delete
This commit is contained in:
parent
c528936abb
commit
82b070e7ac
@ -139,17 +139,14 @@ pub async fn create_post(
|
||||
|
||||
tx.commit().await.map_err(AppError::tx)?;
|
||||
|
||||
// 写入成功后失效文章列表、标签与统计缓存。
|
||||
// 写入成功后按粒度失效相关缓存。
|
||||
crate::cache::invalidate_post_lists();
|
||||
crate::cache::invalidate_all_tags();
|
||||
crate::cache::invalidate_post_stats();
|
||||
// 失效按 slug 缓存,避免之前缓存的 404 继续命中。
|
||||
crate::cache::invalidate_post_by_slug(&final_slug).await;
|
||||
|
||||
// 失效该文章涉及的所有标签缓存。
|
||||
for tag_name in &tags_cleaned {
|
||||
crate::cache::invalidate_posts_by_tag(tag_name).await;
|
||||
}
|
||||
// 失效该文章涉及的所有标签下文章列表缓存。
|
||||
crate::cache::invalidate_tag_posts_for(&tags_cleaned).await;
|
||||
|
||||
Ok(CreatePostResponse {
|
||||
success: true,
|
||||
|
||||
@ -27,6 +27,34 @@ pub async fn delete_post(post_id: i32) -> Result<CreatePostResponse, ServerFnErr
|
||||
{
|
||||
let client = get_conn().await.map_err(AppError::db_conn)?;
|
||||
|
||||
// 在软删除前查询 slug 与标签,用于后续精准失效缓存。
|
||||
let slug_row = client
|
||||
.query_opt(
|
||||
"SELECT slug FROM posts WHERE id = $1 AND deleted_at IS NULL",
|
||||
&[&post_id],
|
||||
)
|
||||
.await
|
||||
.map_err(AppError::query)?;
|
||||
|
||||
let Some(slug_row) = slug_row else {
|
||||
return Ok(CreatePostResponse {
|
||||
success: false,
|
||||
message: "文章不存在".to_string(),
|
||||
post_id: None,
|
||||
slug: None,
|
||||
});
|
||||
};
|
||||
let slug: String = slug_row.get(0);
|
||||
|
||||
let tag_rows = client
|
||||
.query(
|
||||
"SELECT t.name FROM tags t JOIN post_tags pt ON t.id = pt.tag_id WHERE pt.post_id = $1",
|
||||
&[&post_id],
|
||||
)
|
||||
.await
|
||||
.map_err(AppError::query)?;
|
||||
let tags: Vec<String> = tag_rows.iter().map(|r| r.get(0)).collect();
|
||||
|
||||
// 软删除:仅影响未被删除的文章。
|
||||
let result = client
|
||||
.execute(
|
||||
@ -45,14 +73,18 @@ pub async fn delete_post(post_id: i32) -> Result<CreatePostResponse, ServerFnErr
|
||||
});
|
||||
}
|
||||
|
||||
// 删除后所有文章相关缓存均失效。
|
||||
crate::cache::invalidate_all_post_caches();
|
||||
// 删除后按影响范围精准失效缓存。
|
||||
crate::cache::invalidate_post_lists();
|
||||
crate::cache::invalidate_all_tags();
|
||||
crate::cache::invalidate_post_stats();
|
||||
crate::cache::invalidate_post_by_slug(&slug).await;
|
||||
crate::cache::invalidate_tag_posts_for(&tags).await;
|
||||
|
||||
Ok(CreatePostResponse {
|
||||
success: true,
|
||||
message: "删除成功".to_string(),
|
||||
post_id: Some(post_id),
|
||||
slug: None,
|
||||
slug: Some(slug),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -198,17 +198,17 @@ pub async fn update_post(
|
||||
// 失效文章列表、标签、当前 slug 与统计缓存。
|
||||
crate::cache::invalidate_post_lists();
|
||||
crate::cache::invalidate_all_tags();
|
||||
crate::cache::invalidate_post_by_slug(&final_slug).await;
|
||||
crate::cache::invalidate_post_stats();
|
||||
crate::cache::invalidate_post_by_slug(&final_slug).await;
|
||||
|
||||
// 合并旧标签与新标签,统一失效标签下的文章列表缓存。
|
||||
let all_tags_to_invalidate: std::collections::HashSet<String> = old_tags
|
||||
let all_tags_to_invalidate: Vec<String> = old_tags
|
||||
.into_iter()
|
||||
.chain(tags_for_invalidation.into_iter())
|
||||
.collect::<std::collections::HashSet<_>>()
|
||||
.into_iter()
|
||||
.collect();
|
||||
for tag_name in &all_tags_to_invalidate {
|
||||
crate::cache::invalidate_posts_by_tag(tag_name).await;
|
||||
}
|
||||
crate::cache::invalidate_tag_posts_for(&all_tags_to_invalidate).await;
|
||||
|
||||
// 若 slug 发生变更,额外失效旧 slug 缓存。
|
||||
if let Some(ref old) = old_slug {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user