Browse Source

feat: room(分区)

master
hole-thu 3 years ago
parent
commit
0e1a088575
  1. 3
      migrations/postgres/2022-08-18-234900_add_room_id/down.sql
  2. 3
      migrations/postgres/2022-08-18-234900_add_room_id/up.sql
  3. 2
      src/api/mod.rs
  4. 1
      src/api/operation.rs
  5. 17
      src/api/post.rs
  6. 4
      src/api/search.rs
  7. 15
      src/cache.rs
  8. 4
      src/main.rs
  9. 32
      src/models.rs
  10. 1
      src/schema.rs

3
migrations/postgres/2022-08-18-234900_add_room_id/down.sql

@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
ALTER TABLE posts
DROP COLUMN room_id

3
migrations/postgres/2022-08-18-234900_add_room_id/up.sql

@ -0,0 +1,3 @@
-- Your SQL goes here
ALTER TABLE posts
ADD COLUMN room_id INTEGER NOT NULL DEFAULT 0

2
src/api/mod.rs

@ -235,7 +235,7 @@ impl Ugc for Post {
self.is_deleted
}
fn extra_delete_condition(&self) -> bool {
!self.content.starts_with("[系统自动代发]\n")
self.room_id != 42
}
async fn do_set_deleted(&mut self, db: &Db) -> Api<()> {
update!(*self, posts, db, { is_deleted, to true });

1
src/api/operation.rs

@ -140,6 +140,7 @@ pub async fn report(ri: Form<ReportInput>, user: CurrentUser, db: Db, rconn: Rds
is_tmp: false,
n_attentions: 1,
allow_search: true,
room_id: 42,
},
)
.await?;

17
src/api/post.rs

@ -26,12 +26,14 @@ pub struct PostInput {
use_title: Option<i8>,
#[field(validate = len(0..97))]
poll_options: Vec<String>,
room_id: Option<i32>,
}
#[derive(Serialize)]
#[serde(crate = "rocket::serde")]
pub struct PostOutput {
pid: i32,
room_id: i32,
text: String,
cw: Option<String>,
author_title: Option<String>,
@ -84,6 +86,7 @@ async fn p2output(p: &Post, user: &CurrentUser, db: &Db, rconn: &RdsConn) -> Api
user.is_admin || (!is_blocked && user.id.is_some() || user.namehash.eq(&p.author_hash));
Ok(PostOutput {
pid: p.id,
room_id: p.room_id,
text: can_view.then(|| p.content.clone()).unwrap_or_default(),
cw: (!p.cw.is_empty()).then(|| p.cw.clone()),
n_attentions: p.n_attentions,
@ -144,10 +147,11 @@ pub async fn get_one(pid: i32, user: CurrentUser, db: Db, rconn: RdsConn) -> Jso
}))
}
#[get("/getlist?<p>&<order_mode>")]
#[get("/getlist?<p>&<order_mode>&<room_id>")]
pub async fn get_list(
p: Option<u32>,
order_mode: u8,
room_id: Option<i32>,
user: CurrentUser,
db: Db,
rconn: RdsConn,
@ -156,7 +160,15 @@ pub async fn get_list(
let page = p.unwrap_or(1);
let page_size = 25;
let start = (page - 1) * page_size;
let ps = Post::gets_by_page(&db, &rconn, order_mode, start.into(), page_size.into()).await?;
let ps = Post::gets_by_page(
&db,
&rconn,
room_id,
order_mode,
start.into(),
page_size.into(),
)
.await?;
let ps_data = ps2outputs(&ps, &user, &db, &rconn).await?;
Ok(json!({
"data": ps_data,
@ -184,6 +196,7 @@ pub async fn publish_post(
is_tmp: user.id.is_none(),
n_attentions: 1,
allow_search: poi.allow_search.is_some(),
room_id: poi.room_id.unwrap_or_default(),
},
)
.await?;

4
src/api/search.rs

@ -5,8 +5,9 @@ use crate::models::*;
use crate::rds_conn::RdsConn;
use rocket::serde::json::json;
#[get("/search?<search_mode>&<page>&<keywords>")]
#[get("/search?<search_mode>&<page>&<keywords>&<room_id>")]
pub async fn search(
room_id: Option<i32>,
keywords: String,
search_mode: u8,
page: i32,
@ -25,6 +26,7 @@ pub async fn search(
Post::search(
&db,
&rconn,
room_id,
search_mode,
keywords.to_string(),
start.into(),

15
src/cache.rs

@ -172,17 +172,24 @@ impl PostCommentCache {
}
}
pub struct PostListCommentCache {
pub struct PostListCache {
key: String,
mode: u8,
rconn: RdsConn,
length: isize,
}
impl PostListCommentCache {
pub fn init(mode: u8, rconn: &RdsConn) -> Self {
impl PostListCache {
pub fn init(room_id: Option<i32>, mode: u8, rconn: &RdsConn) -> Self {
Self {
key: format!("hole_v2:cache:post_list:{}", &mode),
key: format!(
"hole_v2:cache:post_list:{}:{}",
match room_id {
Some(i) => i.to_string(),
None => "".to_owned(),
},
&mode
),
mode,
rconn: rconn.clone(),
length: 0,

4
src/main.rs

@ -54,7 +54,9 @@ async fn main() -> Result<(), rocket::Error> {
let rconn = RdsConn(rmc.clone());
tokio::spawn(async move {
loop {
cache::PostListCommentCache::init(3, &rconn).clear().await;
for room_id in [None, Some(0), Some(1), Some(42)] {
cache::PostListCache::init(room_id, 3, &rconn).clear().await;
}
sleep(Duration::from_secs(5 * 60)).await;
}
});

32
src/models.rs

@ -119,6 +119,7 @@ pub struct Post {
pub is_reported: bool,
pub hot_score: i32,
pub allow_search: bool,
pub room_id: i32,
}
#[derive(Queryable, Insertable, Serialize, Deserialize, Debug)]
@ -140,6 +141,7 @@ pub struct NewPost {
pub is_tmp: bool,
pub n_attentions: i32,
pub allow_search: bool,
pub room_id: i32,
}
impl Post {
@ -215,19 +217,21 @@ impl Post {
pub async fn gets_by_page(
db: &Db,
rconn: &RdsConn,
room_id: Option<i32>,
order_mode: u8,
start: i64,
limit: i64,
) -> QueryResult<Vec<Self>> {
let mut cacher = PostListCommentCache::init(order_mode, &rconn);
let mut cacher = PostListCache::init(room_id, order_mode, &rconn);
if cacher.need_fill().await {
let pids =
Self::_get_ids_by_page(db, order_mode.clone(), 0, cacher.i64_minlen()).await?;
Self::_get_ids_by_page(db, room_id, order_mode.clone(), 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, order_mode, start, limit).await?
Self::_get_ids_by_page(db, room_id, order_mode, start, limit).await?
} else {
cacher.get_pids(start, limit).await
};
@ -236,6 +240,7 @@ impl Post {
}
async fn _get_ids_by_page(
db: &Db,
room_id: Option<i32>,
order_mode: u8,
start: i64,
limit: i64,
@ -243,7 +248,11 @@ impl Post {
db.run(move |c| {
let mut query = base_query!(posts).select(posts::id);
if order_mode > 0 {
query = query.filter(posts::is_reported.eq(false))
query = query.filter(posts::is_reported.eq(false));
}
if let Some(ri) = room_id {
query = query.filter(posts::room_id.eq(ri));
}
query = match order_mode {
@ -262,6 +271,7 @@ impl Post {
pub async fn search(
db: &Db,
rconn: &RdsConn,
room_id: Option<i32>,
search_mode: u8,
search_text: String,
start: i64,
@ -276,6 +286,9 @@ impl Post {
.distinct()
.left_join(comments::table)
.filter(posts::is_reported.eq(false));
if let Some(ri) = room_id {
query = query.filter(posts::room_id.eq(ri));
}
// 先用搜索+缓存,性能有问题了再真的做tag表
query = match search_mode {
0 => {
@ -334,9 +347,12 @@ impl Post {
join!(
self.set_instance_cache(rconn),
future::join_all((if is_new { 0..4 } else { 1..4 }).map(|mode| async move {
PostListCommentCache::init(mode, &rconn.clone())
PostListCache::init(None, mode, &rconn.clone())
.put(self)
.await
.await;
PostListCache::init(Some(self.room_id), mode, &rconn.clone())
.put(self)
.await;
})),
);
}
@ -349,7 +365,9 @@ impl Post {
.unwrap();
PostCache::init(&rconn).clear_all().await;
PostListCommentCache::init(2, rconn).clear().await
for room_id in [None, Some(0), Some(1), Some(42)] {
PostListCache::init(room_id, 2, rconn).clear().await;
}
}
}

1
src/schema.rs

@ -28,6 +28,7 @@ table! {
is_reported -> Bool,
hot_score -> Int4,
allow_search -> Bool,
room_id -> Int4,
}
}

Loading…
Cancel
Save