cache in memory
This commit is contained in:
112
src/models.rs
112
src/models.rs
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user