cache in memory

This commit is contained in:
2026-03-23 22:14:01 +08:00
parent fae30ed97a
commit 8e386d98d0
13 changed files with 318 additions and 392 deletions

View File

@@ -3,7 +3,6 @@
use crate::cache::*;
use crate::db_conn::{Conn, Db};
use crate::random_hasher::random_string;
use crate::rds_conn::RdsConn;
use crate::schema::*;
use chrono::{offset::Utc, DateTime};
use diesel::sql_types::*;
@@ -93,7 +92,7 @@ macro_rules! with_log {
};
}
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug)]
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug, Clone)]
#[serde(crate = "rocket::serde")]
pub struct Comment {
pub id: i32,
@@ -107,7 +106,7 @@ pub struct Comment {
pub post_id: i32,
}
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug)]
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug, Clone)]
#[serde(crate = "rocket::serde")]
pub struct Post {
pub id: i32,
@@ -129,7 +128,7 @@ pub struct Post {
pub down_votes: i32,
}
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug)]
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug, Clone)]
#[serde(crate = "rocket::serde")]
pub struct User {
pub id: i32,
@@ -156,9 +155,8 @@ impl Post {
_get_multi!(posts);
pub async fn get_multi(db: &Db, rconn: &RdsConn, ids: &[i32]) -> QueryResult<Vec<Self>> {
let mut cacher = PostCache::init(rconn);
let mut cached_posts = cacher.gets(ids).await;
pub async fn get_multi(db: &Db, ids: &[i32]) -> QueryResult<Vec<Self>> {
let mut cached_posts = PostCache::gets(ids).await;
let mut id2po = HashMap::<i32, &mut Option<Post>>::new();
// dbg!(&cached_posts);
@@ -180,7 +178,7 @@ impl Post {
let missing_ps = Self::_get_multi(db, missing_ids).await?;
// dbg!(&missing_ps);
cacher.sets(&missing_ps.iter().collect::<Vec<_>>()).await;
PostCache::sets(&missing_ps.iter().collect::<Vec<_>>()).await;
for p in missing_ps.into_iter() {
if let Some(op) = id2po.get_mut(&p.id) {
@@ -194,55 +192,52 @@ impl Post {
.collect())
}
pub async fn get(db: &Db, rconn: &RdsConn, id: i32) -> QueryResult<Self> {
pub async fn get(db: &Db, id: i32) -> QueryResult<Self> {
// 注意即使is_deleted也应该缓存和返回
let mut cacher = PostCache::init(rconn);
if let Some(p) = cacher.get(&id).await {
Ok(p)
} else {
let p = Self::_get(db, id).await?;
cacher.sets(&[&p]).await;
Ok(p)
}
PostCache::get_with(id, async move { Self::_get(db, id).await }).await
}
pub async fn get_comments(&self, db: &Db, rconn: &RdsConn) -> QueryResult<Vec<Comment>> {
let mut cacher = PostCommentCache::init(self.id, rconn);
if let Some(cs) = cacher.get().await {
Ok(cs)
} else {
let cs = Comment::gets_by_post_id(db, self.id).await?;
cacher.set(&cs).await;
Ok(cs)
}
pub async fn get_comments(&self, db: &Db) -> QueryResult<Vec<Comment>> {
let cacher = PostCommentCache::init(self.id);
cacher
.get_with(async move { Comment::gets_by_post_id(db, self.id).await })
.await
}
pub async fn clear_comments_cache(&self, rconn: &RdsConn) {
PostCommentCache::init(self.id, rconn).clear().await;
pub async fn clear_comments_cache(&self) {
PostCommentCache::init(self.id).clear().await;
}
pub async fn gets_by_page(
db: &Db,
rconn: &RdsConn,
room_id: Option<i32>,
order_mode: u8,
start: i64,
limit: i64,
start: usize,
limit: usize,
) -> QueryResult<Vec<Self>> {
let mut cacher = PostListCache::init(room_id, order_mode, rconn);
if cacher.need_fill().await {
let pids =
Self::_get_ids_by_page(db, room_id, order_mode, 0, cacher.i64_minlen()).await?;
let ps = Self::get_multi(db, rconn, &pids).await?;
cacher.fill(&ps).await;
}
let pids = if start + limit > cacher.i64_len() {
Self::_get_ids_by_page(db, room_id, order_mode, start, limit).await?
let mut cacher = PostListCache::init(room_id, order_mode);
let current_len = cacher
.fill_with(async move {
let pids = Self::_get_ids_by_page(
db,
room_id,
order_mode,
0,
PostListCache::MAX_LENGTH as i64,
)
.await?;
Self::get_multi(db, &pids).await
})
.await?;
let pids = if start + limit > current_len {
Self::_get_ids_by_page(db, room_id, order_mode, start as i64, limit as i64).await?
} else {
cacher.get_pids(start, limit).await
};
Self::get_multi(db, rconn, &pids).await
Self::get_multi(db, &pids).await
}
async fn _get_ids_by_page(
db: &Db,
@@ -281,7 +276,6 @@ impl Post {
pub async fn search(
db: &Db,
rconn: &RdsConn,
room_id: Option<i32>,
search_mode: u8,
search_text: String,
@@ -339,7 +333,7 @@ impl Post {
.load(with_log!(c))
})
.await?;
Self::get_multi(db, rconn, &pids).await
Self::get_multi(db, &pids).await
}
pub async fn create(db: &Db, new_post: NewPost) -> QueryResult<Self> {
@@ -351,18 +345,16 @@ impl Post {
.await
}
pub async fn set_instance_cache(&self, rconn: &RdsConn) {
PostCache::init(rconn).sets(&[self]).await;
pub async fn set_instance_cache(&self) {
PostCache::sets(&[self]).await;
}
pub async fn refresh_cache(&self, rconn: &RdsConn, is_new: bool) {
pub async fn refresh_cache(&self, is_new: bool) {
join!(
self.set_instance_cache(rconn),
self.set_instance_cache(),
future::join_all((if is_new { [0, 2, 3, 4] } else { [1, 2, 3, 4] }).map(
|mode| async move {
PostListCache::init(None, mode, &rconn.clone())
.put(self)
.await;
PostListCache::init(Some(self.room_id), mode, &rconn.clone())
PostListCache::init(None, mode).put(self).await;
PostListCache::init(Some(self.room_id), mode)
.put(self)
.await;
}
@@ -370,16 +362,16 @@ impl Post {
);
}
pub async fn annealing(c: &mut Conn, rconn: &mut RdsConn) {
pub async fn annealing(c: &mut Conn) {
info!("Time for annealing!");
diesel::update(posts::table.filter(posts::hot_score.gt(10)))
.set(posts::hot_score.eq(floor(float4(posts::hot_score) * 0.9)))
.execute(with_log!(c))
.unwrap();
PostCache::clear_all(rconn).await;
PostCache::clear_all().await;
for room_id in (0..5).map(Some).chain([None, Some(42)]) {
PostListCache::init(room_id, 2, rconn).clear().await;
PostListCache::init(room_id, 2).clear().await;
}
}
}
@@ -396,7 +388,11 @@ impl User {
.ok()
}
pub async fn get_by_token(db: &Db, rconn: &RdsConn, token: &str) -> Option<Self> {
pub async fn get_by_token(db: &Db, token: &str) -> Option<Self> {
let mut cacher = UserCache::init(token);
if let Some(u) = cacher.get().await {
return Some(u);
}
let real_token;
let token = match &token.split(':').collect::<Vec<&str>>()[..] {
@@ -410,7 +406,7 @@ impl User {
_ => token,
};
// dbg!(token);
let mut cacher = UserCache::init(token, rconn);
let mut cacher = UserCache::init(token);
if let Some(u) = cacher.get().await {
Some(u)
} else {
@@ -452,11 +448,11 @@ impl User {
.await
}
pub async fn clear_non_admin_users(c: &mut Conn, rconn: &mut RdsConn) {
pub async fn clear_non_admin_users(c: &mut Conn) {
diesel::delete(users::table.filter(users::is_admin.eq(false)))
.execute(c)
.unwrap();
UserCache::clear_all(rconn).await;
UserCache::clear_all().await;
}
pub async fn get_count(db: &Db) -> QueryResult<i64> {