refactor(posts): avoid redundant cache invalidation in bulk fallback paths
This commit is contained in:
parent
c77f751377
commit
2d8f1e0d98
@ -321,47 +321,61 @@ pub async fn batch_purge_posts(post_ids: Vec<i32>) -> Result<CreatePostResponse,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = get_conn().await.map_err(AppError::db_conn)?;
|
let mut client = get_conn().await.map_err(AppError::db_conn)?;
|
||||||
|
let tx = client.transaction().await.map_err(AppError::tx)?;
|
||||||
let total = post_ids.len() as i64;
|
let total = post_ids.len() as i64;
|
||||||
|
|
||||||
// 记录数较少时查询 slug 与标签,使用精准失效;否则回退到全量失效。
|
// 记录数较少时锁定行并读取 slug 与标签,使用精准失效;否则回退到全量失效。
|
||||||
let use_precise = post_ids.len() <= PRECISE_INVALIDATION_LIMIT;
|
let use_precise = post_ids.len() <= PRECISE_INVALIDATION_LIMIT;
|
||||||
let (slugs, tags) = if use_precise {
|
let (slugs, tags) = if use_precise {
|
||||||
let slug_rows = client
|
let mut slugs = Vec::with_capacity(post_ids.len());
|
||||||
.query(
|
let mut tags_set: std::collections::HashSet<String> =
|
||||||
"SELECT slug FROM posts WHERE id = ANY($1) AND deleted_at IS NOT NULL",
|
std::collections::HashSet::new();
|
||||||
&[&post_ids],
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(AppError::query)?;
|
|
||||||
let slugs: Vec<String> = slug_rows.iter().map(|r| r.get(0)).collect();
|
|
||||||
|
|
||||||
let tag_rows = client
|
for id in &post_ids {
|
||||||
.query(
|
let slug_row = tx
|
||||||
"SELECT t.name FROM tags t JOIN post_tags pt ON t.id = pt.tag_id WHERE pt.post_id = ANY($1)",
|
.query_opt(
|
||||||
&[&post_ids],
|
"SELECT slug FROM posts WHERE id = $1 AND deleted_at IS NOT NULL FOR UPDATE",
|
||||||
)
|
&[&id],
|
||||||
.await
|
)
|
||||||
.map_err(AppError::query)?;
|
.await
|
||||||
let tags: Vec<String> = tag_rows.iter().map(|r| r.get(0)).collect();
|
.map_err(AppError::query)?;
|
||||||
|
|
||||||
(slugs, tags)
|
if let Some(slug_row) = slug_row {
|
||||||
|
let slug: String = slug_row.get(0);
|
||||||
|
let tag_rows = tx
|
||||||
|
.query(
|
||||||
|
"SELECT t.name FROM tags t JOIN post_tags pt ON t.id = pt.tag_id WHERE pt.post_id = $1",
|
||||||
|
&[&id],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(AppError::query)?;
|
||||||
|
for tag_row in &tag_rows {
|
||||||
|
tags_set.insert(tag_row.get(0));
|
||||||
|
}
|
||||||
|
slugs.push(slug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(slugs, tags_set.into_iter().collect::<Vec<_>>())
|
||||||
} else {
|
} else {
|
||||||
(Vec::new(), Vec::new())
|
(Vec::new(), Vec::new())
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = client
|
let result = tx
|
||||||
.execute(
|
.execute(
|
||||||
"DELETE FROM posts WHERE id = ANY($1) AND deleted_at IS NOT NULL",
|
"DELETE FROM posts WHERE id = ANY($1) AND deleted_at IS NOT NULL",
|
||||||
&[&post_ids],
|
&[&post_ids],
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(AppError::query)?;
|
.map_err(AppError::tx)?;
|
||||||
|
|
||||||
|
tx.commit().await.map_err(AppError::tx)?;
|
||||||
|
|
||||||
crate::cache::invalidate_post_lists();
|
|
||||||
crate::cache::invalidate_all_tags();
|
|
||||||
crate::cache::invalidate_post_stats();
|
|
||||||
if use_precise {
|
if use_precise {
|
||||||
|
crate::cache::invalidate_post_lists();
|
||||||
|
crate::cache::invalidate_all_tags();
|
||||||
|
crate::cache::invalidate_post_stats();
|
||||||
for slug in &slugs {
|
for slug in &slugs {
|
||||||
crate::cache::invalidate_post_by_slug(slug).await;
|
crate::cache::invalidate_post_by_slug(slug).await;
|
||||||
}
|
}
|
||||||
@ -439,10 +453,10 @@ pub async fn empty_trash() -> Result<CreatePostResponse, ServerFnError> {
|
|||||||
.await
|
.await
|
||||||
.map_err(AppError::query)?;
|
.map_err(AppError::query)?;
|
||||||
|
|
||||||
crate::cache::invalidate_post_lists();
|
|
||||||
crate::cache::invalidate_all_tags();
|
|
||||||
crate::cache::invalidate_post_stats();
|
|
||||||
if use_precise {
|
if use_precise {
|
||||||
|
crate::cache::invalidate_post_lists();
|
||||||
|
crate::cache::invalidate_all_tags();
|
||||||
|
crate::cache::invalidate_post_stats();
|
||||||
for slug in &slugs {
|
for slug in &slugs {
|
||||||
crate::cache::invalidate_post_by_slug(slug).await;
|
crate::cache::invalidate_post_by_slug(slug).await;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user