mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-15 00:43:59 +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},
|
traits::{Actor, Object},
|
||||||
};
|
};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use itertools::Itertools;
|
|
||||||
use lemmy_api_common::{
|
use lemmy_api_common::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
utils::{generate_featured_url, generate_moderators_url, generate_outbox_url},
|
utils::{generate_featured_url, generate_moderators_url, generate_outbox_url},
|
||||||
|
@ -188,17 +187,11 @@ impl ApubCommunity {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
|
|
||||||
let local_site_data = local_site_data_cached(context.pool()).await?;
|
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
|
let inboxes: Vec<Url> = follows
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|f| !f.follower.local)
|
.map(Into::into)
|
||||||
.map(|f| {
|
|
||||||
f.follower
|
|
||||||
.shared_inbox_url
|
|
||||||
.unwrap_or(f.follower.inbox_url)
|
|
||||||
.into()
|
|
||||||
})
|
|
||||||
.unique()
|
|
||||||
.filter(|inbox: &Url| inbox.host_str() != Some(&context.settings().hostname))
|
.filter(|inbox: &Url| inbox.host_str() != Some(&context.settings().hostname))
|
||||||
// Don't send to blocked instances
|
// Don't send to blocked instances
|
||||||
.filter(|inbox| check_apub_id_valid(inbox, &local_site_data).is_ok())
|
.filter(|inbox| check_apub_id_valid(inbox, &local_site_data).is_ok())
|
||||||
|
|
|
@ -22,12 +22,12 @@ impl GroupFollowers {
|
||||||
) -> Result<GroupFollowers, LemmyError> {
|
) -> Result<GroupFollowers, LemmyError> {
|
||||||
let community_id = community.id;
|
let community_id = community.id;
|
||||||
let community_followers =
|
let community_followers =
|
||||||
CommunityFollowerView::for_community(context.pool(), community_id).await?;
|
CommunityFollowerView::count_community_followers(context.pool(), community_id).await?;
|
||||||
|
|
||||||
Ok(GroupFollowers {
|
Ok(GroupFollowers {
|
||||||
id: generate_followers_url(&community.actor_id)?.into(),
|
id: generate_followers_url(&community.actor_id)?.into(),
|
||||||
r#type: CollectionType::Collection,
|
r#type: CollectionType::Collection,
|
||||||
total_items: community_followers.len() as i32,
|
total_items: community_followers as i32,
|
||||||
items: vec![],
|
items: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
use crate::structs::CommunityFollowerView;
|
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 diesel_async::RunQueryDsl;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::{CommunityId, PersonId},
|
newtypes::{CommunityId, DbUrl, PersonId},
|
||||||
schema::{community, community_follower, person},
|
schema::{community, community_follower, person},
|
||||||
source::{community::Community, person::Person},
|
source::{community::Community, person::Person},
|
||||||
traits::JoinView,
|
traits::JoinView,
|
||||||
|
@ -11,19 +17,37 @@ use lemmy_db_schema::{
|
||||||
|
|
||||||
type CommunityFollowerViewTuple = (Community, Person);
|
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 {
|
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 conn = &mut get_conn(pool).await?;
|
||||||
let res = community_follower::table
|
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))
|
.filter(community_follower::community_id.eq(community_id))
|
||||||
.order_by(community::title)
|
.filter(not(person::local))
|
||||||
.load::<CommunityFollowerViewTuple>(conn)
|
.inner_join(person::table)
|
||||||
|
.select(coalesce(person::shared_inbox_url, person::inbox_url))
|
||||||
|
.distinct()
|
||||||
|
.load::<DbUrl>(conn)
|
||||||
.await?;
|
.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> {
|
pub async fn for_person(pool: &DbPool, person_id: PersonId) -> Result<Vec<Self>, Error> {
|
||||||
|
|
Loading…
Reference in a new issue