mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-25 19:01:03 +00:00
Cache result of LocalSite::read to avoid unnecessary db calls (#4585)
* Cache result of LocalSite::read to avoid unnecessary db calls * single const for cache duration * clippy * revert apub send changes * clippy * fmt
This commit is contained in:
parent
aaaa362b98
commit
087684658a
8 changed files with 44 additions and 28 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2772,6 +2772,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"i-love-jesus",
|
||||
"lemmy_utils",
|
||||
"moka",
|
||||
"once_cell",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
|
|
|
@ -42,21 +42,18 @@ use lemmy_utils::{
|
|||
markdown::{markdown_check_for_blocked_urls, markdown_rewrite_image_links},
|
||||
slurs::{build_slur_regex, remove_slurs},
|
||||
},
|
||||
CACHE_DURATION_SHORT,
|
||||
};
|
||||
use moka::future::Cache;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::{escape, Regex, RegexSet};
|
||||
use rosetta_i18n::{Language, LanguageId};
|
||||
use std::{collections::HashSet, time::Duration};
|
||||
use std::collections::HashSet;
|
||||
use tracing::warn;
|
||||
use url::{ParseError, Url};
|
||||
use urlencoding::encode;
|
||||
|
||||
pub static AUTH_COOKIE_NAME: &str = "jwt";
|
||||
#[cfg(debug_assertions)]
|
||||
static URL_BLOCKLIST_RECHECK_DELAY: Duration = Duration::from_millis(500);
|
||||
#[cfg(not(debug_assertions))]
|
||||
static URL_BLOCKLIST_RECHECK_DELAY: Duration = Duration::from_secs(60);
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn is_mod_or_admin(
|
||||
|
@ -527,7 +524,7 @@ pub async fn get_url_blocklist(context: &LemmyContext) -> LemmyResult<RegexSet>
|
|||
static URL_BLOCKLIST: Lazy<Cache<(), RegexSet>> = Lazy::new(|| {
|
||||
Cache::builder()
|
||||
.max_capacity(1)
|
||||
.time_to_live(URL_BLOCKLIST_RECHECK_DELAY)
|
||||
.time_to_live(CACHE_DURATION_SHORT)
|
||||
.build()
|
||||
});
|
||||
|
||||
|
|
|
@ -20,11 +20,11 @@ use lemmy_db_views_actor::structs::{
|
|||
};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyError, LemmyErrorExt, LemmyErrorType},
|
||||
CACHE_DURATION_SHORT,
|
||||
VERSION,
|
||||
};
|
||||
use moka::future::Cache;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::time::Duration;
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn get_site(
|
||||
|
@ -34,7 +34,7 @@ pub async fn get_site(
|
|||
static CACHE: Lazy<Cache<(), GetSiteResponse>> = Lazy::new(|| {
|
||||
Cache::builder()
|
||||
.max_capacity(1)
|
||||
.time_to_live(Duration::from_secs(1))
|
||||
.time_to_live(CACHE_DURATION_SHORT)
|
||||
.build()
|
||||
});
|
||||
|
||||
|
|
|
@ -9,11 +9,14 @@ use lemmy_db_schema::{
|
|||
source::{activity::ReceivedActivity, instance::Instance, local_site::LocalSite},
|
||||
utils::{ActualDbPool, DbPool},
|
||||
};
|
||||
use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult};
|
||||
use lemmy_utils::{
|
||||
error::{LemmyError, LemmyErrorType, LemmyResult},
|
||||
CACHE_DURATION_SHORT,
|
||||
};
|
||||
use moka::future::Cache;
|
||||
use once_cell::sync::Lazy;
|
||||
use serde_json::Value;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use std::sync::Arc;
|
||||
use url::Url;
|
||||
|
||||
pub mod activities;
|
||||
|
@ -27,11 +30,6 @@ pub mod objects;
|
|||
pub mod protocol;
|
||||
|
||||
pub const FEDERATION_HTTP_FETCH_LIMIT: u32 = 50;
|
||||
/// All incoming and outgoing federation actions read the blocklist/allowlist and slur filters
|
||||
/// multiple times. This causes a huge number of database reads if we hit the db directly. So we
|
||||
/// cache these values for a short time, which will already make a huge difference and ensures that
|
||||
/// changes take effect quickly.
|
||||
const BLOCKLIST_CACHE_DURATION: Duration = Duration::from_secs(60);
|
||||
|
||||
/// Only include a basic context to save space and bandwidth. The main context is hosted statically
|
||||
/// on join-lemmy.org. Include activitystreams explicitly for better compat, but this could
|
||||
|
@ -122,10 +120,14 @@ pub(crate) struct LocalSiteData {
|
|||
pub(crate) async fn local_site_data_cached(
|
||||
pool: &mut DbPool<'_>,
|
||||
) -> LemmyResult<Arc<LocalSiteData>> {
|
||||
// All incoming and outgoing federation actions read the blocklist/allowlist and slur filters
|
||||
// multiple times. This causes a huge number of database reads if we hit the db directly. So we
|
||||
// cache these values for a short time, which will already make a huge difference and ensures that
|
||||
// changes take effect quickly.
|
||||
static CACHE: Lazy<Cache<(), Arc<LocalSiteData>>> = Lazy::new(|| {
|
||||
Cache::builder()
|
||||
.max_capacity(1)
|
||||
.time_to_live(BLOCKLIST_CACHE_DURATION)
|
||||
.time_to_live(CACHE_DURATION_SHORT)
|
||||
.build()
|
||||
});
|
||||
Ok(
|
||||
|
|
|
@ -80,6 +80,7 @@ rustls = { workspace = true, optional = true }
|
|||
uuid = { workspace = true, features = ["v4"] }
|
||||
i-love-jesus = { workspace = true, optional = true }
|
||||
anyhow = { workspace = true }
|
||||
moka.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = { workspace = true }
|
||||
|
|
|
@ -5,6 +5,9 @@ use crate::{
|
|||
};
|
||||
use diesel::{dsl::insert_into, result::Error};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_utils::{error::LemmyError, CACHE_DURATION_SHORT};
|
||||
use moka::future::Cache;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
impl LocalSite {
|
||||
pub async fn create(pool: &mut DbPool<'_>, form: &LocalSiteInsertForm) -> Result<Self, Error> {
|
||||
|
@ -14,9 +17,21 @@ impl LocalSite {
|
|||
.get_result::<Self>(conn)
|
||||
.await
|
||||
}
|
||||
pub async fn read(pool: &mut DbPool<'_>) -> Result<Self, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
local_site.first::<Self>(conn).await
|
||||
pub async fn read(pool: &mut DbPool<'_>) -> Result<Self, LemmyError> {
|
||||
static CACHE: Lazy<Cache<(), LocalSite>> = Lazy::new(|| {
|
||||
Cache::builder()
|
||||
.max_capacity(1)
|
||||
.time_to_live(CACHE_DURATION_SHORT)
|
||||
.build()
|
||||
});
|
||||
Ok(
|
||||
CACHE
|
||||
.try_get_with((), async {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
local_site.first::<Self>(conn).await
|
||||
})
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
pub async fn update(pool: &mut DbPool<'_>, form: &LocalSiteUpdateForm) -> Result<Self, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use anyhow::{anyhow, Context, Result};
|
||||
use diesel::prelude::*;
|
||||
use diesel_async::RunQueryDsl;
|
||||
use lemmy_api_common::lemmy_utils::CACHE_DURATION_SHORT;
|
||||
use lemmy_apub::{
|
||||
activity_lists::SharedInboxActivities,
|
||||
fetcher::{site_or_community_or_user::SiteOrCommunityOrUser, user_or_community::UserOrCommunity},
|
||||
|
@ -31,6 +32,7 @@ pub(crate) static LEMMY_TEST_FAST_FEDERATION: Lazy<bool> = Lazy::new(|| {
|
|||
.map(|s| !s.is_empty())
|
||||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
/// Recheck for new federation work every n seconds.
|
||||
///
|
||||
/// When the queue is processed faster than new activities are added and it reaches the current time with an empty batch,
|
||||
|
@ -167,15 +169,8 @@ pub(crate) async fn get_activity_cached(
|
|||
|
||||
/// return the most current activity id (with 1 second cache)
|
||||
pub(crate) async fn get_latest_activity_id(pool: &mut DbPool<'_>) -> Result<ActivityId> {
|
||||
static CACHE: Lazy<Cache<(), ActivityId>> = Lazy::new(|| {
|
||||
Cache::builder()
|
||||
.time_to_live(if *LEMMY_TEST_FAST_FEDERATION {
|
||||
*WORK_FINISHED_RECHECK_DELAY
|
||||
} else {
|
||||
Duration::from_secs(1)
|
||||
})
|
||||
.build()
|
||||
});
|
||||
static CACHE: Lazy<Cache<(), ActivityId>> =
|
||||
Lazy::new(|| Cache::builder().time_to_live(CACHE_DURATION_SHORT).build());
|
||||
CACHE
|
||||
.try_get_with((), async {
|
||||
use diesel::dsl::max;
|
||||
|
|
|
@ -23,6 +23,11 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
|||
|
||||
pub const REQWEST_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub const CACHE_DURATION_SHORT: Duration = Duration::from_millis(500);
|
||||
#[cfg(not(debug_assertions))]
|
||||
pub const CACHE_DURATION_SHORT: Duration = Duration::from_secs(60);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! location_info {
|
||||
() => {
|
||||
|
|
Loading…
Reference in a new issue