perf (backend-rs): reduce note copy operations

This commit is contained in:
naskya 2024-05-21 16:12:11 +09:00
parent 1f082bfb56
commit da9fe83986
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
4 changed files with 28 additions and 25 deletions

View file

@ -1,4 +1,3 @@
pub mod check_hit_antenna;
pub mod check_server_block;
pub mod check_word_mute;
pub mod convert_host;

View file

@ -1,7 +1,8 @@
use crate::database::{cache, db_conn, redis_conn, redis_key, RedisConnError};
use crate::federation::acct::Acct;
use crate::misc::check_hit_antenna::{check_hit_antenna, AntennaCheckError};
use crate::misc::get_note_all_texts::{all_texts, NoteLike};
use crate::model::entity::{antenna, note};
use crate::service::antenna::check_hit::{check_hit_antenna, AntennaCheckError};
use crate::service::stream;
use crate::util::id::{get_timestamp, InvalidIdErr};
use redis::{streams::StreamMaxlen, AsyncCommands, RedisError};
@ -46,15 +47,29 @@ async fn antennas() -> Result<Vec<Antenna>, Error> {
pub async fn update_antennas_on_new_note(
note: Note,
note_author: &Acct,
note_muted_users: Vec<String>,
note_muted_users: &[String],
) -> Result<(), Error> {
let note_cloned = note.clone();
let note_all_texts = all_texts(
NoteLike {
file_ids: note.file_ids,
user_id: note.user_id,
text: note.text,
cw: note.cw,
renote_id: note.renote_id,
reply_id: note.reply_id,
},
false,
)
.await?;
// TODO: do this in parallel
for antenna in antennas().await?.iter() {
if note_muted_users.contains(&antenna.user_id) {
continue;
}
if check_hit_antenna(antenna, note.clone(), note_author).await? {
add_note_to_antenna(&antenna.id, &note).await?;
if check_hit_antenna(antenna, &note_cloned, &note_all_texts, note_author).await? {
add_note_to_antenna(&antenna.id, &note_cloned).await?;
}
}

View file

@ -1,18 +1,17 @@
use crate::config::CONFIG;
use crate::database::{cache, db_conn};
use crate::federation::acct::Acct;
use crate::misc::get_note_all_texts::{all_texts, NoteLike};
use crate::model::entity::{antenna, blocking, following, note, sea_orm_active_enums::*};
use sea_orm::{ColumnTrait, DbErr, EntityTrait, QueryFilter, QuerySelect};
#[derive(thiserror::Error, Debug)]
pub enum AntennaCheckError {
#[error("Database error: {0}")]
DbErr(#[from] DbErr),
Db(#[from] DbErr),
#[error("Cache error: {0}")]
CacheErr(#[from] cache::Error),
Cache(#[from] cache::Error),
#[error("User profile not found: {0}")]
UserProfileNotFoundErr(String),
UserProfileNotFound(String),
}
fn match_all(space_separated_words: &str, text: &str, case_sensitive: bool) -> bool {
@ -30,7 +29,8 @@ fn match_all(space_separated_words: &str, text: &str, case_sensitive: bool) -> b
pub async fn check_hit_antenna(
antenna: &antenna::Model,
note: note::Model,
note: &note::Model,
note_all_texts: &[String],
note_author: &Acct,
) -> Result<bool, AntennaCheckError> {
if note.visibility == NoteVisibilityEnum::Specified {
@ -72,21 +72,8 @@ pub async fn check_hit_antenna(
// "Home", "Group", "List" sources are currently disabled
let note_texts = all_texts(
NoteLike {
file_ids: note.file_ids,
user_id: note.user_id.clone(),
text: note.text,
cw: note.cw,
renote_id: note.renote_id,
reply_id: note.reply_id,
},
false,
)
.await?;
let has_keyword = antenna.keywords.iter().any(|words| {
note_texts
note_all_texts
.iter()
.any(|text| match_all(words, text, antenna.case_sensitive))
});
@ -96,7 +83,7 @@ pub async fn check_hit_antenna(
}
let has_excluded_word = antenna.exclude_keywords.iter().any(|words| {
note_texts
note_all_texts
.iter()
.any(|text| match_all(words, text, antenna.case_sensitive))
});

View file

@ -0,0 +1,2 @@
pub mod add_new_note;
mod check_hit;