From 095ee483ac491c3086cd63f6c15d2d787f64c314 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 30 Sep 2024 21:29:16 -0700 Subject: [PATCH] move auth_chain_cache to service --- src/database.rs | 10 ----- src/database/key_value/rooms/auth_chain.rs | 36 +++------------ src/service.rs | 12 ++++- src/service/rooms/auth_chain.rs | 51 +++++++++++++++++++--- src/service/rooms/auth_chain/data.rs | 8 ++-- 5 files changed, 65 insertions(+), 52 deletions(-) diff --git a/src/database.rs b/src/database.rs index ba3709cd..e506f4f1 100644 --- a/src/database.rs +++ b/src/database.rs @@ -236,8 +236,6 @@ pub(crate) struct KeyValueDatabase { pub(super) senderkey_pusher: Arc, // Uncategorized trees - pub(super) auth_chain_cache: - Mutex, Arc>>>, pub(super) eventidshort_cache: Mutex>, pub(super) statekeyshort_cache: Mutex>, @@ -466,14 +464,6 @@ impl KeyValueDatabase { global: builder.open_tree("global")?, server_signingkeys: builder.open_tree("server_signingkeys")?, - #[allow( - clippy::as_conversions, - clippy::cast_sign_loss, - clippy::cast_possible_truncation - )] - auth_chain_cache: Mutex::new(LruCache::new( - (100_000.0 * config.cache_capacity_modifier) as usize, - )), #[allow( clippy::as_conversions, clippy::cast_sign_loss, diff --git a/src/database/key_value/rooms/auth_chain.rs b/src/database/key_value/rooms/auth_chain.rs index b29149f8..b736e524 100644 --- a/src/database/key_value/rooms/auth_chain.rs +++ b/src/database/key_value/rooms/auth_chain.rs @@ -1,8 +1,7 @@ -use std::{collections::HashSet, mem::size_of, sync::Arc}; +use std::{collections::HashSet, mem::size_of}; use crate::{ database::KeyValueDatabase, - observability::{FoundIn, Lookup, METRICS}, service::{self, rooms::short::ShortEventId}, utils, Result, }; @@ -12,19 +11,9 @@ impl service::rooms::auth_chain::Data for KeyValueDatabase { fn get_cached_eventid_authchain( &self, key: &[ShortEventId], - ) -> Result>>> { - let lookup = Lookup::AuthChain; - - // Check RAM cache - if let Some(result) = self.auth_chain_cache.lock().unwrap().get_mut(key) - { - METRICS.record_lookup(lookup, FoundIn::Cache); - return Ok(Some(Arc::clone(result))); - } - + ) -> Result>> { // We only save auth chains for single events in the db if key.len() == 1 { - // Check DB cache let chain = self .shorteventid_authchain .get(&key[0].get().to_be_bytes())? @@ -40,28 +29,16 @@ impl service::rooms::auth_chain::Data for KeyValueDatabase { .collect() }); - if let Some(chain) = chain { - METRICS.record_lookup(lookup, FoundIn::Database); - let chain = Arc::new(chain); - - // Cache in RAM - self.auth_chain_cache - .lock() - .unwrap() - .insert(vec![key[0]], Arc::clone(&chain)); - - return Ok(Some(chain)); - } + return Ok(chain); } - METRICS.record_lookup(lookup, FoundIn::Nothing); Ok(None) } fn cache_auth_chain( &self, - key: Vec, - auth_chain: Arc>, + key: &[ShortEventId], + auth_chain: &HashSet, ) -> Result<()> { // Only persist single events in db if key.len() == 1 { @@ -74,9 +51,6 @@ impl service::rooms::auth_chain::Data for KeyValueDatabase { )?; } - // Cache in RAM - self.auth_chain_cache.lock().unwrap().insert(key, auth_chain); - Ok(()) } } diff --git a/src/service.rs b/src/service.rs index 6f038ecb..c5725f83 100644 --- a/src/service.rs +++ b/src/service.rs @@ -71,9 +71,17 @@ impl Services { }, rooms: rooms::Service { alias: rooms::alias::Service::new(db), - auth_chain: rooms::auth_chain::Service { + auth_chain: rooms::auth_chain::Service::new( db, - }, + #[allow( + clippy::as_conversions, + clippy::cast_sign_loss, + clippy::cast_possible_truncation + )] + { + (100_000.0 * config.cache_capacity_modifier) as usize + }, + ), directory: db, edus: rooms::edus::Service { read_receipt: db, diff --git a/src/service/rooms/auth_chain.rs b/src/service/rooms/auth_chain.rs index c5a62a6d..97c95f11 100644 --- a/src/service/rooms/auth_chain.rs +++ b/src/service/rooms/auth_chain.rs @@ -1,28 +1,67 @@ use std::{ collections::{BTreeSet, HashSet}, - sync::Arc, + sync::{Arc, Mutex}, }; +use lru_cache::LruCache; use ruma::{api::client::error::ErrorKind, EventId, RoomId}; use tracing::{debug, error, warn}; use super::short::ShortEventId; -use crate::{services, utils::debug_slice_truncated, Error, Result}; +use crate::{ + observability::{FoundIn, Lookup, METRICS}, + services, + utils::debug_slice_truncated, + Error, Result, +}; mod data; pub(crate) use data::Data; pub(crate) struct Service { - pub(crate) db: &'static dyn Data, + db: &'static dyn Data, + auth_chain_cache: + Mutex, Arc>>>, } impl Service { + pub(crate) fn new( + db: &'static dyn Data, + auth_chain_cache_size: usize, + ) -> Self { + Self { + db, + auth_chain_cache: Mutex::new(LruCache::new(auth_chain_cache_size)), + } + } + pub(crate) fn get_cached_eventid_authchain( &self, key: &[ShortEventId], ) -> Result>>> { - self.db.get_cached_eventid_authchain(key) + let lookup = Lookup::AuthChain; + + if let Some(result) = self.auth_chain_cache.lock().unwrap().get_mut(key) + { + METRICS.record_lookup(lookup, FoundIn::Cache); + return Ok(Some(Arc::clone(result))); + } + + let Some(chain) = self.db.get_cached_eventid_authchain(key)? else { + METRICS.record_lookup(lookup, FoundIn::Nothing); + return Ok(None); + }; + + METRICS.record_lookup(lookup, FoundIn::Database); + let chain = Arc::new(chain); + + self.auth_chain_cache + .lock() + .unwrap() + .insert(vec![key[0]], Arc::clone(&chain)); + + Ok(Some(chain)) } #[tracing::instrument(skip(self))] @@ -31,7 +70,9 @@ impl Service { key: Vec, auth_chain: Arc>, ) -> Result<()> { - self.db.cache_auth_chain(key, auth_chain) + self.db.cache_auth_chain(&key, &auth_chain)?; + self.auth_chain_cache.lock().unwrap().insert(key, auth_chain); + Ok(()) } #[tracing::instrument( diff --git a/src/service/rooms/auth_chain/data.rs b/src/service/rooms/auth_chain/data.rs index 5d01b1e2..9dc855d2 100644 --- a/src/service/rooms/auth_chain/data.rs +++ b/src/service/rooms/auth_chain/data.rs @@ -1,4 +1,4 @@ -use std::{collections::HashSet, sync::Arc}; +use std::collections::HashSet; use crate::{service::rooms::short::ShortEventId, Result}; @@ -6,10 +6,10 @@ pub(crate) trait Data: Send + Sync { fn get_cached_eventid_authchain( &self, shorteventid: &[ShortEventId], - ) -> Result>>>; + ) -> Result>>; fn cache_auth_chain( &self, - shorteventid: Vec, - auth_chain: Arc>, + shorteventid: &[ShortEventId], + auth_chain: &HashSet, ) -> Result<()>; }