refactor (backend-rs): rework static cache
Co-authored-by: sup39 <dev@sup39.dev>
This commit is contained in:
parent
d5919b21fb
commit
8584bb439b
9 changed files with 90 additions and 48 deletions
53
packages/backend-rs/src/cache/bare.rs
vendored
Normal file
53
packages/backend-rs/src/cache/bare.rs
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
//! In-memory cache handler
|
||||||
|
|
||||||
|
use chrono::{DateTime, Duration, Utc};
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
pub struct Cache<T: Clone> {
|
||||||
|
cache: Mutex<TimedData<T>>,
|
||||||
|
ttl: Option<Duration>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TimedData<T: Clone> {
|
||||||
|
value: Option<T>,
|
||||||
|
last_updated: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Clone> Cache<T> {
|
||||||
|
pub const fn new(ttl: Option<Duration>) -> Self {
|
||||||
|
Self {
|
||||||
|
cache: Mutex::new(TimedData {
|
||||||
|
value: None,
|
||||||
|
last_updated: DateTime::UNIX_EPOCH,
|
||||||
|
}),
|
||||||
|
ttl,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&self, value: T) {
|
||||||
|
if self.ttl.is_none() {
|
||||||
|
let _ = self
|
||||||
|
.cache
|
||||||
|
.lock()
|
||||||
|
.map(|mut cache| (*cache).value = Some(value));
|
||||||
|
} else {
|
||||||
|
let _ = self.cache.lock().map(|mut cache| {
|
||||||
|
*cache = TimedData {
|
||||||
|
value: Some(value),
|
||||||
|
last_updated: Utc::now(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self) -> Option<T> {
|
||||||
|
let data = self.cache.lock().ok()?;
|
||||||
|
|
||||||
|
if let Some(ttl) = self.ttl {
|
||||||
|
if data.last_updated + ttl < Utc::now() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.value.to_owned()
|
||||||
|
}
|
||||||
|
}
|
3
packages/backend-rs/src/cache/mod.rs
vendored
Normal file
3
packages/backend-rs/src/cache/mod.rs
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod bare;
|
||||||
|
|
||||||
|
pub use bare::Cache;
|
|
@ -1,15 +1,11 @@
|
||||||
//! Server information
|
//! Server information
|
||||||
|
|
||||||
use crate::{database::db_conn, model::entity::meta};
|
use crate::{cache::Cache, database::db_conn, model::entity::meta};
|
||||||
use sea_orm::{prelude::*, ActiveValue};
|
use sea_orm::{prelude::*, ActiveValue};
|
||||||
use std::sync::Mutex;
|
|
||||||
|
|
||||||
type Meta = meta::Model;
|
type Meta = meta::Model;
|
||||||
|
|
||||||
static CACHE: Mutex<Option<Meta>> = Mutex::new(None);
|
static INSTANCE_META_CACHE: Cache<Meta> = Cache::new(None);
|
||||||
fn set_cache(meta: &Meta) {
|
|
||||||
let _ = CACHE.lock().map(|mut cache| *cache = Some(meta.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macros::export(js_name = "fetchMeta")]
|
#[macros::export(js_name = "fetchMeta")]
|
||||||
pub async fn local_server_info() -> Result<Meta, DbErr> {
|
pub async fn local_server_info() -> Result<Meta, DbErr> {
|
||||||
|
@ -25,7 +21,7 @@ pub async fn update() -> Result<(), DbErr> {
|
||||||
async fn local_server_info_impl(use_cache: bool) -> Result<Meta, DbErr> {
|
async fn local_server_info_impl(use_cache: bool) -> Result<Meta, DbErr> {
|
||||||
// try using cache
|
// try using cache
|
||||||
if use_cache {
|
if use_cache {
|
||||||
if let Some(cache) = CACHE.lock().ok().and_then(|cache| cache.clone()) {
|
if let Some(cache) = INSTANCE_META_CACHE.get() {
|
||||||
return Ok(cache);
|
return Ok(cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +30,7 @@ async fn local_server_info_impl(use_cache: bool) -> Result<Meta, DbErr> {
|
||||||
let db = db_conn().await?;
|
let db = db_conn().await?;
|
||||||
let meta = meta::Entity::find().one(db).await?;
|
let meta = meta::Entity::find().one(db).await?;
|
||||||
if let Some(meta) = meta {
|
if let Some(meta) = meta {
|
||||||
set_cache(&meta);
|
INSTANCE_META_CACHE.set(meta.clone());
|
||||||
return Ok(meta);
|
return Ok(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +41,7 @@ async fn local_server_info_impl(use_cache: bool) -> Result<Meta, DbErr> {
|
||||||
})
|
})
|
||||||
.exec_with_returning(db)
|
.exec_with_returning(db)
|
||||||
.await?;
|
.await?;
|
||||||
set_cache(&meta);
|
INSTANCE_META_CACHE.set(meta.clone());
|
||||||
Ok(meta)
|
Ok(meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! NodeInfo generator
|
//! NodeInfo generator
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
cache::Cache,
|
||||||
config::{local_server_info, CONFIG},
|
config::{local_server_info, CONFIG},
|
||||||
database::db_conn,
|
database::db_conn,
|
||||||
federation::nodeinfo::schema::*,
|
federation::nodeinfo::schema::*,
|
||||||
|
@ -9,15 +10,9 @@ use crate::{
|
||||||
};
|
};
|
||||||
use sea_orm::prelude::*;
|
use sea_orm::prelude::*;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::{collections::HashMap, sync::Mutex};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
static CACHE: Mutex<Option<Nodeinfo21>> = Mutex::new(None);
|
static NODEINFO_CACHE: Cache<Nodeinfo21> = Cache::new(None);
|
||||||
|
|
||||||
fn set_cache(nodeinfo: &Nodeinfo21) {
|
|
||||||
let _ = CACHE
|
|
||||||
.lock()
|
|
||||||
.map(|mut cache| *cache = Some(nodeinfo.to_owned()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fetches the number of total/active local users and local posts.
|
/// Fetches the number of total/active local users and local posts.
|
||||||
///
|
///
|
||||||
|
@ -129,7 +124,7 @@ async fn generate_nodeinfo_2_1() -> Result<Nodeinfo21, DbErr> {
|
||||||
|
|
||||||
async fn nodeinfo_2_1_impl(use_cache: bool) -> Result<Nodeinfo21, DbErr> {
|
async fn nodeinfo_2_1_impl(use_cache: bool) -> Result<Nodeinfo21, DbErr> {
|
||||||
if use_cache {
|
if use_cache {
|
||||||
if let Some(nodeinfo) = CACHE.lock().ok().and_then(|cache| cache.to_owned()) {
|
if let Some(nodeinfo) = NODEINFO_CACHE.get() {
|
||||||
return Ok(nodeinfo);
|
return Ok(nodeinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +132,7 @@ async fn nodeinfo_2_1_impl(use_cache: bool) -> Result<Nodeinfo21, DbErr> {
|
||||||
let nodeinfo = generate_nodeinfo_2_1().await?;
|
let nodeinfo = generate_nodeinfo_2_1().await?;
|
||||||
|
|
||||||
tracing::info!("updating cache");
|
tracing::info!("updating cache");
|
||||||
set_cache(&nodeinfo);
|
NODEINFO_CACHE.set(nodeinfo.clone());
|
||||||
|
|
||||||
Ok(nodeinfo)
|
Ok(nodeinfo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
|
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
|
||||||
|
|
||||||
|
pub mod cache;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod database;
|
pub mod database;
|
||||||
pub mod federation;
|
pub mod federation;
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
//! In-memory antennas cache handler
|
|
||||||
|
|
||||||
use crate::{database::db_conn, model::entity::antenna};
|
|
||||||
use sea_orm::prelude::*;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
static CACHE: Mutex<Option<Arc<[antenna::Model]>>> = Mutex::new(None);
|
|
||||||
|
|
||||||
fn set(antennas: Arc<[antenna::Model]>) {
|
|
||||||
let _ = CACHE.lock().map(|mut cache| *cache = Some(antennas));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) async fn update() -> Result<Arc<[antenna::Model]>, DbErr> {
|
|
||||||
tracing::debug!("updating cache");
|
|
||||||
let antennas: Arc<[antenna::Model]> =
|
|
||||||
antenna::Entity::find().all(db_conn().await?).await?.into();
|
|
||||||
set(antennas.clone());
|
|
||||||
Ok(antennas)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) async fn get() -> Result<Arc<[antenna::Model]>, DbErr> {
|
|
||||||
if let Some(cache) = CACHE.lock().ok().and_then(|cache| cache.clone()) {
|
|
||||||
return Ok(cache);
|
|
||||||
}
|
|
||||||
update().await
|
|
||||||
}
|
|
|
@ -1,4 +1,24 @@
|
||||||
mod cache;
|
|
||||||
mod check_hit;
|
mod check_hit;
|
||||||
pub mod process_new_note;
|
pub mod process_new_note;
|
||||||
pub mod update;
|
pub mod update;
|
||||||
|
|
||||||
|
use crate::{cache::Cache, database::db_conn, model::entity::antenna};
|
||||||
|
use sea_orm::prelude::*;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
static ANTENNAS_CACHE: Cache<Arc<[antenna::Model]>> = Cache::new(None);
|
||||||
|
|
||||||
|
async fn update() -> Result<Arc<[antenna::Model]>, DbErr> {
|
||||||
|
tracing::debug!("updating cache");
|
||||||
|
let antennas: Arc<[antenna::Model]> =
|
||||||
|
antenna::Entity::find().all(db_conn().await?).await?.into();
|
||||||
|
ANTENNAS_CACHE.set(antennas.clone());
|
||||||
|
Ok(antennas)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_antennas() -> Result<Arc<[antenna::Model]>, DbErr> {
|
||||||
|
if let Some(cache) = ANTENNAS_CACHE.get() {
|
||||||
|
return Ok(cache);
|
||||||
|
}
|
||||||
|
update().await
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ pub async fn update_antennas_on_new_note(
|
||||||
let note_all_texts = elaborate!(note, false).await?;
|
let note_all_texts = elaborate!(note, false).await?;
|
||||||
|
|
||||||
// TODO: do this in parallel
|
// TODO: do this in parallel
|
||||||
for antenna in antenna::cache::get().await?.iter() {
|
for antenna in antenna::get_antennas().await?.iter() {
|
||||||
if note_muted_users.contains(&antenna.user_id) {
|
if note_muted_users.contains(&antenna.user_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
#[macros::ts_export]
|
#[macros::ts_export]
|
||||||
pub async fn update_antenna_cache() -> Result<(), sea_orm::DbErr> {
|
pub async fn update_antenna_cache() -> Result<(), sea_orm::DbErr> {
|
||||||
super::cache::update().await?;
|
super::update().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue