mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-23 11:21:32 +00:00
improve performance of community followers inbox query (#3482)
* improve performance of community followers inbox query * nightly format * force woodpecker to retry --------- Co-authored-by: Dessalines <dessalines@users.noreply.github.com>
This commit is contained in:
parent
ebaf69bd70
commit
45b1a0d4fb
3 changed files with 38 additions and 21 deletions
|
@ -14,7 +14,6 @@ use activitypub_federation::{
|
|||
traits::{Actor, Object},
|
||||
};
|
||||
use chrono::NaiveDateTime;
|
||||
use itertools::Itertools;
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
utils::{generate_featured_url, generate_moderators_url, generate_outbox_url},
|
||||
|
@ -188,17 +187,11 @@ impl ApubCommunity {
|
|||
let id = self.id;
|
||||
|
||||
let local_site_data = local_site_data_cached(context.pool()).await?;
|
||||
let follows = CommunityFollowerView::for_community(context.pool(), id).await?;
|
||||
let follows = CommunityFollowerView::get_community_follower_inboxes(context.pool(), id).await?;
|
||||
|
||||
let inboxes: Vec<Url> = follows
|
||||
.into_iter()
|
||||
.filter(|f| !f.follower.local)
|
||||
.map(|f| {
|
||||
f.follower
|
||||
.shared_inbox_url
|
||||
.unwrap_or(f.follower.inbox_url)
|
||||
.into()
|
||||
})
|
||||
.unique()
|
||||
.map(Into::into)
|
||||
.filter(|inbox: &Url| inbox.host_str() != Some(&context.settings().hostname))
|
||||
// Don't send to blocked instances
|
||||
.filter(|inbox| check_apub_id_valid(inbox, &local_site_data).is_ok())
|
||||
|
|
|
@ -22,12 +22,12 @@ impl GroupFollowers {
|
|||
) -> Result<GroupFollowers, LemmyError> {
|
||||
let community_id = community.id;
|
||||
let community_followers =
|
||||
CommunityFollowerView::for_community(context.pool(), community_id).await?;
|
||||
CommunityFollowerView::count_community_followers(context.pool(), community_id).await?;
|
||||
|
||||
Ok(GroupFollowers {
|
||||
id: generate_followers_url(&community.actor_id)?.into(),
|
||||
r#type: CollectionType::Collection,
|
||||
total_items: community_followers.len() as i32,
|
||||
total_items: community_followers as i32,
|
||||
items: vec![],
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
use crate::structs::CommunityFollowerView;
|
||||
use diesel::{result::Error, ExpressionMethods, QueryDsl};
|
||||
use diesel::{
|
||||
dsl::{count_star, not},
|
||||
result::Error,
|
||||
sql_function,
|
||||
ExpressionMethods,
|
||||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_db_schema::{
|
||||
newtypes::{CommunityId, PersonId},
|
||||
newtypes::{CommunityId, DbUrl, PersonId},
|
||||
schema::{community, community_follower, person},
|
||||
source::{community::Community, person::Person},
|
||||
traits::JoinView,
|
||||
|
@ -11,19 +17,37 @@ use lemmy_db_schema::{
|
|||
|
||||
type CommunityFollowerViewTuple = (Community, Person);
|
||||
|
||||
sql_function!(fn coalesce(x: diesel::sql_types::Nullable<diesel::sql_types::Text>, y: diesel::sql_types::Text) -> diesel::sql_types::Text);
|
||||
|
||||
impl CommunityFollowerView {
|
||||
pub async fn for_community(pool: &DbPool, community_id: CommunityId) -> Result<Vec<Self>, Error> {
|
||||
pub async fn get_community_follower_inboxes(
|
||||
pool: &DbPool,
|
||||
community_id: CommunityId,
|
||||
) -> Result<Vec<DbUrl>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let res = community_follower::table
|
||||
.inner_join(community::table)
|
||||
.inner_join(person::table)
|
||||
.select((community::all_columns, person::all_columns))
|
||||
.filter(community_follower::community_id.eq(community_id))
|
||||
.order_by(community::title)
|
||||
.load::<CommunityFollowerViewTuple>(conn)
|
||||
.filter(not(person::local))
|
||||
.inner_join(person::table)
|
||||
.select(coalesce(person::shared_inbox_url, person::inbox_url))
|
||||
.distinct()
|
||||
.load::<DbUrl>(conn)
|
||||
.await?;
|
||||
|
||||
Ok(res.into_iter().map(Self::from_tuple).collect())
|
||||
Ok(res)
|
||||
}
|
||||
pub async fn count_community_followers(
|
||||
pool: &DbPool,
|
||||
community_id: CommunityId,
|
||||
) -> Result<i64, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let res = community_follower::table
|
||||
.filter(community_follower::community_id.eq(community_id))
|
||||
.select(count_star())
|
||||
.first::<i64>(conn)
|
||||
.await?;
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub async fn for_person(pool: &DbPool, person_id: PersonId) -> Result<Vec<Self>, Error> {
|
||||
|
|
Loading…
Reference in a new issue