diff --git a/Cargo.lock b/Cargo.lock index b62cf624c..edc6722bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2550,7 +2550,6 @@ dependencies = [ "lemmy_db_views", "lemmy_db_views_actor", "lemmy_utils", - "moka", "serde", "serde_json", "serde_with", @@ -2632,7 +2631,6 @@ dependencies = [ "futures-util", "i-love-jesus", "lemmy_utils", - "moka", "pretty_assertions", "regex", "rustls 0.23.16", @@ -2819,6 +2817,7 @@ dependencies = [ "markdown-it-ruby", "markdown-it-sub", "markdown-it-sup", + "moka", "pretty_assertions", "regex", "reqwest-middleware", diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index 48b339e65..d46e57749 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -60,6 +60,7 @@ use lemmy_utils::{ slurs::{build_slur_regex, remove_slurs}, validation::clean_urls_in_text, }, + CacheLock, CACHE_DURATION_FEDERATION, }; use moka::future::Cache; @@ -535,7 +536,7 @@ pub fn local_site_opt_to_slur_regex(local_site: &Option) -> Option LemmyResult { - static URL_BLOCKLIST: LazyLock> = LazyLock::new(|| { + static URL_BLOCKLIST: CacheLock = LazyLock::new(|| { Cache::builder() .max_capacity(1) .time_to_live(CACHE_DURATION_FEDERATION) diff --git a/crates/api_crud/Cargo.toml b/crates/api_crud/Cargo.toml index 723864705..3f1a00ccd 100644 --- a/crates/api_crud/Cargo.toml +++ b/crates/api_crud/Cargo.toml @@ -25,7 +25,6 @@ tracing = { workspace = true } url = { workspace = true } futures.workspace = true uuid = { workspace = true } -moka.workspace = true anyhow.workspace = true chrono.workspace = true webmention = "0.6.0" diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index 47fd1f154..6bee0fda6 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -16,11 +16,11 @@ use lemmy_db_schema::source::{ use lemmy_db_views::structs::{LocalUserView, SiteView}; use lemmy_db_views_actor::structs::{CommunityFollowerView, CommunityModeratorView, PersonView}; use lemmy_utils::{ - error::{LemmyError, LemmyErrorExt, LemmyErrorType, LemmyResult}, - CACHE_DURATION_API, + build_cache, + error::{LemmyErrorExt, LemmyErrorType, LemmyResult}, + CacheLock, VERSION, }; -use moka::future::Cache; use std::sync::LazyLock; #[tracing::instrument(skip(context))] @@ -28,41 +28,10 @@ pub async fn get_site( local_user_view: Option, context: Data, ) -> LemmyResult> { - static CACHE: LazyLock> = LazyLock::new(|| { - Cache::builder() - .max_capacity(1) - .time_to_live(CACHE_DURATION_API) - .build() - }); - // This data is independent from the user account so we can cache it across requests + static CACHE: CacheLock = LazyLock::new(build_cache); let mut site_response = CACHE - .try_get_with::<_, LemmyError>((), async { - let site_view = SiteView::read_local(&mut context.pool()).await?; - let admins = PersonView::admins(&mut context.pool()).await?; - let all_languages = Language::read_all(&mut context.pool()).await?; - let discussion_languages = SiteLanguage::read_local_raw(&mut context.pool()).await?; - let blocked_urls = LocalSiteUrlBlocklist::get_all(&mut context.pool()).await?; - let tagline = Tagline::get_random(&mut context.pool()).await.ok(); - let admin_oauth_providers = OAuthProvider::get_all(&mut context.pool()).await?; - let oauth_providers = - OAuthProvider::convert_providers_to_public(admin_oauth_providers.clone()); - - Ok(GetSiteResponse { - site_view, - admins, - version: VERSION.to_string(), - my_user: None, - all_languages, - discussion_languages, - blocked_urls, - tagline, - oauth_providers: Some(oauth_providers), - admin_oauth_providers: Some(admin_oauth_providers), - taglines: vec![], - custom_emojis: vec![], - }) - }) + .try_get_with((), read_site(&context)) .await .map_err(|e| anyhow::anyhow!("Failed to construct site response: {e}"))?; @@ -112,3 +81,29 @@ pub async fn get_site( Ok(Json(site_response)) } + +async fn read_site(context: &LemmyContext) -> LemmyResult { + let site_view = SiteView::read_local(&mut context.pool()).await?; + let admins = PersonView::admins(&mut context.pool()).await?; + let all_languages = Language::read_all(&mut context.pool()).await?; + let discussion_languages = SiteLanguage::read_local_raw(&mut context.pool()).await?; + let blocked_urls = LocalSiteUrlBlocklist::get_all(&mut context.pool()).await?; + let tagline = Tagline::get_random(&mut context.pool()).await.ok(); + let admin_oauth_providers = OAuthProvider::get_all(&mut context.pool()).await?; + let oauth_providers = OAuthProvider::convert_providers_to_public(admin_oauth_providers.clone()); + + Ok(GetSiteResponse { + site_view, + admins, + version: VERSION.to_string(), + my_user: None, + all_languages, + discussion_languages, + blocked_urls, + tagline, + oauth_providers: Some(oauth_providers), + admin_oauth_providers: Some(admin_oauth_providers), + taglines: vec![], + custom_emojis: vec![], + }) +} diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 213f6439d..028d673c2 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -11,6 +11,7 @@ use lemmy_db_schema::{ }; use lemmy_utils::{ error::{FederationError, LemmyError, LemmyErrorType, LemmyResult}, + CacheLock, CACHE_DURATION_FEDERATION, }; use moka::future::Cache; @@ -139,7 +140,7 @@ pub(crate) async fn local_site_data_cached( // 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: LazyLock>> = LazyLock::new(|| { + static CACHE: CacheLock> = LazyLock::new(|| { Cache::builder() .max_capacity(1) .time_to_live(CACHE_DURATION_FEDERATION) diff --git a/crates/db_schema/Cargo.toml b/crates/db_schema/Cargo.toml index c52629ce3..bd83ede29 100644 --- a/crates/db_schema/Cargo.toml +++ b/crates/db_schema/Cargo.toml @@ -79,7 +79,6 @@ uuid = { workspace = true, features = ["v4"] } i-love-jesus = { workspace = true, optional = true } anyhow = { workspace = true } diesel-bind-if-some = { workspace = true, optional = true } -moka.workspace = true derive-new.workspace = true tuplex = { workspace = true, optional = true } diff --git a/crates/db_schema/src/impls/local_site.rs b/crates/db_schema/src/impls/local_site.rs index 926814c48..bdbe4ac6c 100644 --- a/crates/db_schema/src/impls/local_site.rs +++ b/crates/db_schema/src/impls/local_site.rs @@ -5,8 +5,7 @@ use crate::{ }; use diesel::{dsl::insert_into, result::Error}; use diesel_async::RunQueryDsl; -use lemmy_utils::{error::LemmyResult, CACHE_DURATION_API}; -use moka::future::Cache; +use lemmy_utils::{build_cache, error::LemmyResult, CacheLock}; use std::sync::LazyLock; impl LocalSite { @@ -18,12 +17,7 @@ impl LocalSite { .await } pub async fn read(pool: &mut DbPool<'_>) -> LemmyResult { - static CACHE: LazyLock> = LazyLock::new(|| { - Cache::builder() - .max_capacity(1) - .time_to_live(CACHE_DURATION_API) - .build() - }); + static CACHE: CacheLock = LazyLock::new(build_cache); Ok( CACHE .try_get_with((), async { diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml index cd4ea5e9b..7ed4c0476 100644 --- a/crates/utils/Cargo.toml +++ b/crates/utils/Cargo.toml @@ -23,30 +23,31 @@ workspace = true [features] full = [ - "dep:ts-rs", - "dep:diesel", - "dep:rosetta-i18n", - "dep:actix-web", - "dep:reqwest-middleware", - "dep:tracing", - "dep:actix-web", - "dep:serde_json", - "dep:anyhow", - "dep:http", - "dep:deser-hjson", - "dep:regex", - "dep:urlencoding", - "dep:doku", - "dep:url", - "dep:smart-default", - "dep:enum-map", - "dep:futures", - "dep:tokio", - "dep:html2text", - "dep:lettre", - "dep:uuid", - "dep:itertools", - "dep:markdown-it", + "ts-rs", + "diesel", + "rosetta-i18n", + "actix-web", + "reqwest-middleware", + "tracing", + "actix-web", + "serde_json", + "anyhow", + "http", + "deser-hjson", + "regex", + "urlencoding", + "doku", + "url", + "smart-default", + "enum-map", + "futures", + "tokio", + "html2text", + "lettre", + "uuid", + "itertools", + "markdown-it", + "moka", ] [package.metadata.cargo-shear] @@ -89,6 +90,7 @@ markdown-it-block-spoiler = "1.0.0" markdown-it-sub = "1.0.0" markdown-it-sup = "1.0.0" markdown-it-ruby = "1.0.0" +moka = { workspace = true, optional = true } [dev-dependencies] pretty_assertions = { workspace = true } diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs index 1e0cbefbf..3367c91bb 100644 --- a/crates/utils/src/lib.rs +++ b/crates/utils/src/lib.rs @@ -42,7 +42,10 @@ macro_rules! location_info { }; } -#[cfg(feature = "full")] +cfg_if! { + if #[cfg(feature = "full")] { +use moka::future::Cache;use std::fmt::Debug;use std::hash::Hash; + /// tokio::spawn, but accepts a future that may fail and also /// * logs errors /// * attaches the spawned task to the tracing span of the caller for better logging @@ -60,3 +63,20 @@ pub fn spawn_try_task( * spawn was called */ ); } + +pub fn build_cache() -> Cache +where + K: Debug + Eq + Hash + Send + Sync + 'static, + V: Debug + Clone + Send + Sync + 'static, +{ + Cache::::builder() + .max_capacity(1) + .time_to_live(CACHE_DURATION_API) + .build() +} + +#[cfg(feature = "full")] +pub type CacheLock = std::sync::LazyLock>; + + } +}