1
0
Fork 0
forked from alemi/upub

chore(web): moved caches under cache:: scope

This commit is contained in:
əlemi 2024-07-03 03:21:11 +02:00
parent e707bf7344
commit 29d783ffd5
Signed by: alemi
GPG key ID: A4895B84D311642C
15 changed files with 41 additions and 36 deletions

View file

@ -37,7 +37,7 @@ pub fn FollowList(outgoing: bool) -> impl IntoView {
each=move || arr.clone() each=move || arr.clone()
key=|id| id.clone() key=|id| id.clone()
children=move |id| { children=move |id| {
let actor = match CACHE.get(&id) { let actor = match cache::OBJECTS.get(&id) {
Some(x) => x, Some(x) => x,
None => Arc::new(serde_json::Value::String(id)), None => Arc::new(serde_json::Value::String(id)),
}; };

View file

@ -12,14 +12,14 @@ pub fn ActorHeader() -> impl IntoView {
move || params.get().ok().and_then(|x| x.id).unwrap_or_default(), move || params.get().ok().and_then(|x| x.id).unwrap_or_default(),
move |id| { move |id| {
async move { async move {
match CACHE.get(&Uri::full(U::Actor, &id)) { match cache::OBJECTS.get(&Uri::full(U::Actor, &id)) {
Some(x) => Ok::<_, String>(x.clone()), Some(x) => Ok::<_, String>(x.clone()),
None => { None => {
let user : serde_json::Value = Http::fetch(&Uri::api(U::Actor, &id, true), auth) let user : serde_json::Value = Http::fetch(&Uri::api(U::Actor, &id, true), auth)
.await .await
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
let user = std::sync::Arc::new(user); let user = std::sync::Arc::new(user);
CACHE.put(Uri::full(U::Actor, &id), user.clone()); cache::OBJECTS.put(Uri::full(U::Actor, &id), user.clone());
Ok(user) Ok(user)
}, },
} }

View file

@ -11,7 +11,7 @@ pub fn ActivityLine(activity: crate::Object) -> impl IntoView {
<sup><small><a class="clean ml-s" href={x.to_string()} target="_blank">""</a></small></sup> <sup><small><a class="clean ml-s" href={x.to_string()} target="_blank">""</a></small></sup>
}); });
let actor_id = activity.actor().id().str().unwrap_or_default(); let actor_id = activity.actor().id().str().unwrap_or_default();
let actor = CACHE.get_or(&actor_id, serde_json::Value::String(actor_id.clone()).into()); let actor = cache::OBJECTS.get_or(&actor_id, serde_json::Value::String(actor_id.clone()).into());
let kind = activity.activity_type().unwrap_or(apb::ActivityType::Activity); let kind = activity.activity_type().unwrap_or(apb::ActivityType::Activity);
let href = match kind { let href = match kind {
apb::ActivityType::Follow => Uri::web(U::Actor, &object_id), apb::ActivityType::Follow => Uri::web(U::Actor, &object_id),
@ -61,11 +61,11 @@ pub fn Item(
let object_id = item.object().id().str().unwrap_or_default(); let object_id = item.object().id().str().unwrap_or_default();
let object = match t { let object = match t {
apb::ActivityType::Create | apb::ActivityType::Announce => apb::ActivityType::Create | apb::ActivityType::Announce =>
CACHE.get(&object_id).map(|obj| { cache::OBJECTS.get(&object_id).map(|obj| {
view! { <Object object=obj /> } view! { <Object object=obj /> }
}.into_view()), }.into_view()),
apb::ActivityType::Follow => apb::ActivityType::Follow =>
CACHE.get(&object_id).map(|obj| { cache::OBJECTS.get(&object_id).map(|obj| {
view! { view! {
<div class="ml-1"> <div class="ml-1">
<ActorBanner object=obj /> <ActorBanner object=obj />

View file

@ -110,7 +110,7 @@ pub fn Object(object: crate::Object) -> impl IntoView {
let oid = object.id().unwrap_or_default().to_string(); let oid = object.id().unwrap_or_default().to_string();
let content = mdhtml::safe_html(object.content().unwrap_or_default()); let content = mdhtml::safe_html(object.content().unwrap_or_default());
let author_id = object.attributed_to().id().str().unwrap_or_default(); let author_id = object.attributed_to().id().str().unwrap_or_default();
let author = CACHE.get_or(&author_id, serde_json::Value::String(author_id.clone()).into()); let author = cache::OBJECTS.get_or(&author_id, serde_json::Value::String(author_id.clone()).into());
let sensitive = object.sensitive().unwrap_or_default(); let sensitive = object.sensitive().unwrap_or_default();
let addressed = object.addressed(); let addressed = object.addressed();
let public = addressed.iter().any(|x| x.as_str() == apb::target::PUBLIC); let public = addressed.iter().any(|x| x.as_str() == apb::target::PUBLIC);
@ -265,14 +265,14 @@ pub fn LikeButton(
Ok(()) => { Ok(()) => {
set_clicked.set(false); set_clicked.set(false);
set_count.set(count.get() + 1); set_count.set(count.get() + 1);
if let Some(cached) = CACHE.get(&target) { if let Some(cached) = cache::OBJECTS.get(&target) {
let mut new = (*cached).clone().set_liked_by_me(Some(true)); let mut new = (*cached).clone().set_liked_by_me(Some(true));
if let Some(likes) = new.likes().get() { if let Some(likes) = new.likes().get() {
if let Ok(count) = likes.total_items() { if let Ok(count) = likes.total_items() {
new = new.set_likes(apb::Node::object(likes.clone().set_total_items(Some(count + 1)))); new = new.set_likes(apb::Node::object(likes.clone().set_total_items(Some(count + 1))));
} }
} }
CACHE.put(target, Arc::new(new)); cache::OBJECTS.put(target, Arc::new(new));
} }
}, },
Err(e) => tracing::error!("failed sending like: {e}"), Err(e) => tracing::error!("failed sending like: {e}"),

View file

@ -1,7 +1,7 @@
use apb::{field::OptionalString, ActivityMut, Base, BaseMut, Object, ObjectMut}; use apb::{field::OptionalString, ActivityMut, Base, BaseMut, Object, ObjectMut};
use leptos::*; use leptos::*;
use crate::{prelude::*, WEBFINGER}; use crate::prelude::*;
#[derive(Debug, Clone, Copy, Default)] #[derive(Debug, Clone, Copy, Default)]
pub struct ReplyControls { pub struct ReplyControls {
@ -11,7 +11,7 @@ pub struct ReplyControls {
impl ReplyControls { impl ReplyControls {
pub fn reply(&self, oid: &str) { pub fn reply(&self, oid: &str) {
if let Some(obj) = CACHE.get(oid) { if let Some(obj) = cache::OBJECTS.get(oid) {
self.context.set(obj.context().id().str()); self.context.set(obj.context().id().str());
self.reply_to.set(obj.id().ok().map(|x| x.to_string())); self.reply_to.set(obj.id().ok().map(|x| x.to_string()));
} }
@ -24,8 +24,8 @@ impl ReplyControls {
} }
fn post_author(post_id: &str) -> Option<crate::Object> { fn post_author(post_id: &str) -> Option<crate::Object> {
let usr = CACHE.get(post_id)?.attributed_to().id().str()?; let usr = cache::OBJECTS.get(post_id)?.attributed_to().id().str()?;
CACHE.get(&usr) cache::OBJECTS.get(&usr)
} }
#[component] #[component]
@ -51,7 +51,7 @@ pub fn PostBox(advanced: WriteSignal<bool>) -> impl IntoView {
if let Some((user, domain)) = stripped.split_once('@') { if let Some((user, domain)) = stripped.split_once('@') {
if let Some(tld) = domain.split('.').last() { if let Some(tld) = domain.split('.').last() {
if tld::exist(tld) { if tld::exist(tld) {
if let Some(uid) = WEBFINGER.blocking_resolve(user, domain).await { if let Some(uid) = cache::WEBFINGER.blocking_resolve(user, domain).await {
out.push(uid); out.push(uid);
} }
} }
@ -84,7 +84,7 @@ pub fn PostBox(advanced: WriteSignal<bool>) -> impl IntoView {
} }
{move || {move ||
mentions.get() mentions.get()
.map(|x| x.into_iter().map(|u| match CACHE.get(&u) { .map(|x| x.into_iter().map(|u| match cache::OBJECTS.get(&u) {
Some(u) => view! { <span class="nowrap"><span class="emoji mr-s ml-s">"📨"</span><ActorStrip object=u /></span> }.into_view(), Some(u) => view! { <span class="nowrap"><span class="emoji mr-s ml-s">"📨"</span><ActorStrip object=u /></span> }.into_view(),
None => view! { <span class="nowrap"><span class="emoji mr-s ml-s">"📨"</span><a href={Uri::web(U::Actor, &u)}>{u}</a></span> }.into_view(), None => view! { <span class="nowrap"><span class="emoji mr-s ml-s">"📨"</span><a href={Uri::web(U::Actor, &u)}>{u}</a></span> }.into_view(),
}) })

View file

@ -67,7 +67,7 @@ pub fn FollowRequestButtons(activity_id: String, actor_id: String) -> impl IntoV
// TODO lmao what is going on with this double move / triple clone ??????????? // TODO lmao what is going on with this double move / triple clone ???????????
let _activity_id = activity_id.clone(); let _activity_id = activity_id.clone();
let _actor_id = actor_id.clone(); let _actor_id = actor_id.clone();
let from_actor = CACHE.get(&activity_id).map(|x| x.actor().id().str().unwrap_or_default()).unwrap_or_default(); let from_actor = cache::OBJECTS.get(&activity_id).map(|x| x.actor().id().str().unwrap_or_default()).unwrap_or_default();
let _from_actor = from_actor.clone(); let _from_actor = from_actor.clone();
if actor_id == auth.user_id() { if actor_id == auth.user_id() {
Some(view! { Some(view! {

View file

@ -61,7 +61,7 @@ impl FiltersConfig {
let mut reply_filter = true; let mut reply_filter = true;
if let Ok(obj_id) = item.object().id() { if let Ok(obj_id) = item.object().id() {
if let Some(obj) = crate::CACHE.get(obj_id) { if let Some(obj) = crate::cache::OBJECTS.get(obj_id) {
if obj.in_reply_to().id().is_ok() { if obj.in_reply_to().id().is_ok() {
reply_filter = self.replies; reply_filter = self.replies;
} }

View file

@ -26,12 +26,16 @@ pub const DEFAULT_COLOR: &str = "#BF616A";
use std::sync::Arc; use std::sync::Arc;
use uriproxy::UriClass; use uriproxy::UriClass;
pub mod cache {
use super::{ObjectCache, WebfingerCache};
lazy_static::lazy_static! { lazy_static::lazy_static! {
pub static ref CACHE: ObjectCache = ObjectCache::default(); pub static ref OBJECTS: ObjectCache = ObjectCache::default();
pub static ref WEBFINGER: WebfingerCache = WebfingerCache::default(); pub static ref WEBFINGER: WebfingerCache = WebfingerCache::default();
} }
}
}
pub type Object = Arc<serde_json::Value>; pub type Object = Arc<serde_json::Value>;

View file

@ -14,7 +14,7 @@ pub fn ObjectView() -> impl IntoView {
let object = create_local_resource( let object = create_local_resource(
move || params.get().get("id").cloned().unwrap_or_default(), move || params.get().get("id").cloned().unwrap_or_default(),
move |oid| async move { move |oid| async move {
let obj = match CACHE.get(&Uri::full(U::Object, &oid)) { let obj = match cache::OBJECTS.get(&Uri::full(U::Object, &oid)) {
Some(x) => x.clone(), Some(x) => x.clone(),
None => { None => {
let obj = match Http::fetch::<serde_json::Value>(&Uri::api(U::Object, &oid, true), auth).await { let obj = match Http::fetch::<serde_json::Value>(&Uri::api(U::Object, &oid, true), auth).await {
@ -28,10 +28,10 @@ pub fn ObjectView() -> impl IntoView {
if let Ok(user) = Http::fetch::<serde_json::Value>( if let Ok(user) = Http::fetch::<serde_json::Value>(
&Uri::api(U::Actor, author, true), auth &Uri::api(U::Actor, author, true), auth
).await { ).await {
CACHE.put(Uri::full(U::Actor, author), Arc::new(user)); cache::OBJECTS.put(Uri::full(U::Actor, author), Arc::new(user));
} }
} }
CACHE.put(Uri::full(U::Object, &oid), obj.clone()); cache::OBJECTS.put(Uri::full(U::Object, &oid), obj.clone());
obj obj
} }
}; };

View file

@ -19,7 +19,7 @@ pub fn ConfigPage(setter: WriteSignal<crate::Config>) -> impl IntoView {
let avatar_url_ref: NodeRef<html::Input> = create_node_ref(); let avatar_url_ref: NodeRef<html::Input> = create_node_ref();
let banner_url_ref: NodeRef<html::Input> = create_node_ref(); let banner_url_ref: NodeRef<html::Input> = create_node_ref();
let myself = CACHE.get(&auth.userid.get_untracked().unwrap_or_default()); let myself = cache::OBJECTS.get(&auth.userid.get_untracked().unwrap_or_default());
let curr_display_name = myself.as_ref().and_then(|x| Some(x.name().ok()?.to_string())).unwrap_or_default(); let curr_display_name = myself.as_ref().and_then(|x| Some(x.name().ok()?.to_string())).unwrap_or_default();
let curr_summary = myself.as_ref().and_then(|x| Some(x.summary().ok()?.to_string())).unwrap_or_default(); let curr_summary = myself.as_ref().and_then(|x| Some(x.summary().ok()?.to_string())).unwrap_or_default();
let curr_icon = myself.as_ref().and_then(|x| Some(x.icon().get()?.url().id().ok()?.to_string())).unwrap_or_default(); let curr_icon = myself.as_ref().and_then(|x| Some(x.icon().get()?.url().id().ok()?.to_string())).unwrap_or_default();
@ -158,7 +158,7 @@ pub fn ConfigPage(setter: WriteSignal<crate::Config>) -> impl IntoView {
); );
let id = auth.userid.get_untracked().unwrap_or_default(); let id = auth.userid.get_untracked().unwrap_or_default();
let Some(me) = CACHE.get(&id) else { let Some(me) = cache::OBJECTS.get(&id) else {
tracing::error!("self user not in cache! can't update"); tracing::error!("self user not in cache! can't update");
return; return;
}; };

View file

@ -23,7 +23,7 @@ pub fn DebugPage() -> impl IntoView {
set_error.set(false); set_error.set(false);
if query.is_empty() { return serde_json::Value::Null }; if query.is_empty() { return serde_json::Value::Null };
if cached { if cached {
match CACHE.get(&query) { match cache::OBJECTS.get(&query) {
Some(x) => (*x).clone(), Some(x) => (*x).clone(),
None => { None => {
set_error.set(true); set_error.set(true);

View file

@ -1,6 +1,7 @@
pub use crate::{ pub use crate::{
URL_BASE,
Http, Uri, Http, Uri,
CACHE, URL_BASE, cache,
app::{Feeds, Loader}, app::{Feeds, Loader},
auth::Auth, auth::Auth,
page::*, page::*,

View file

@ -19,7 +19,7 @@ pub fn Feed(tl: Timeline) -> impl IntoView {
key=|k| k.to_string() key=|k| k.to_string()
let:id let:id
> >
{match CACHE.get(&id) { {match cache::OBJECTS.get(&id) {
Some(i) => view! { Some(i) => view! {
<Item item=i sep=true /> <Item item=i sep=true />
}.into_view(), }.into_view(),

View file

@ -115,7 +115,7 @@ async fn process_activities(activities: Vec<serde_json::Value>, auth: Auth) -> V
actors_seen.insert(attributed_to); actors_seen.insert(attributed_to);
} }
if let Ok(object_uri) = object.id() { if let Ok(object_uri) = object.id() {
CACHE.put(object_uri.to_string(), Arc::new(object.clone())); cache::OBJECTS.put(object_uri.to_string(), Arc::new(object.clone()));
} else { } else {
tracing::warn!("embedded object without id: {object:?}"); tracing::warn!("embedded object without id: {object:?}");
} }
@ -136,7 +136,7 @@ async fn process_activities(activities: Vec<serde_json::Value>, auth: Auth) -> V
let object_id = activity.object().id().str(); let object_id = activity.object().id().str();
if let Some(activity_id) = activity.id().str() { if let Some(activity_id) = activity.id().str() {
out.push(activity_id.to_string()); out.push(activity_id.to_string());
CACHE.put( cache::OBJECTS.put(
activity_id.to_string(), activity_id.to_string(),
Arc::new(activity.clone().set_object(apb::Node::maybe_link(object_id))) Arc::new(activity.clone().set_object(apb::Node::maybe_link(object_id)))
); );
@ -145,14 +145,14 @@ async fn process_activities(activities: Vec<serde_json::Value>, auth: Auth) -> V
} }
if let Some(uid) = activity.attributed_to().id().str() { if let Some(uid) = activity.attributed_to().id().str() {
if CACHE.get(&uid).is_none() && !gonna_fetch.contains(&uid) { if cache::OBJECTS.get(&uid).is_none() && !gonna_fetch.contains(&uid) {
gonna_fetch.insert(uid.clone()); gonna_fetch.insert(uid.clone());
sub_tasks.push(Box::pin(fetch_and_update(U::Actor, uid, auth))); sub_tasks.push(Box::pin(fetch_and_update(U::Actor, uid, auth)));
} }
} }
if let Some(uid) = activity.actor().id().str() { if let Some(uid) = activity.actor().id().str() {
if CACHE.get(&uid).is_none() && !gonna_fetch.contains(&uid) { if cache::OBJECTS.get(&uid).is_none() && !gonna_fetch.contains(&uid) {
gonna_fetch.insert(uid.clone()); gonna_fetch.insert(uid.clone());
sub_tasks.push(Box::pin(fetch_and_update(U::Actor, uid, auth))); sub_tasks.push(Box::pin(fetch_and_update(U::Actor, uid, auth)));
} }
@ -170,14 +170,14 @@ async fn process_activities(activities: Vec<serde_json::Value>, auth: Auth) -> V
async fn fetch_and_update(kind: U, id: String, auth: Auth) { async fn fetch_and_update(kind: U, id: String, auth: Auth) {
match Http::fetch(&Uri::api(kind, &id, false), auth).await { match Http::fetch(&Uri::api(kind, &id, false), auth).await {
Ok(data) => CACHE.put(id, Arc::new(data)), Ok(data) => cache::OBJECTS.put(id, Arc::new(data)),
Err(e) => console_warn(&format!("could not fetch '{id}': {e}")), Err(e) => console_warn(&format!("could not fetch '{id}': {e}")),
} }
} }
async fn fetch_and_update_with_user(kind: U, id: String, auth: Auth) { async fn fetch_and_update_with_user(kind: U, id: String, auth: Auth) {
fetch_and_update(kind, id.clone(), auth).await; fetch_and_update(kind, id.clone(), auth).await;
if let Some(obj) = CACHE.get(&id) { if let Some(obj) = cache::OBJECTS.get(&id) {
if let Some(actor_id) = match kind { if let Some(actor_id) = match kind {
U::Object => obj.attributed_to().id().str(), U::Object => obj.attributed_to().id().str(),
U::Activity => obj.actor().id().str(), U::Activity => obj.actor().id().str(),

View file

@ -35,11 +35,11 @@ fn FeedRecursive(tl: Timeline, root: String) -> impl IntoView {
.get() .get()
.into_iter() .into_iter()
.filter_map(|x| { .filter_map(|x| {
let document = CACHE.get(&x)?; let document = cache::OBJECTS.get(&x)?;
let (oid, reply) = match document.object_type().ok()? { let (oid, reply) = match document.object_type().ok()? {
// if it's a create, get and check created object: does it reply to root? // if it's a create, get and check created object: does it reply to root?
apb::ObjectType::Activity(apb::ActivityType::Create) => { apb::ObjectType::Activity(apb::ActivityType::Create) => {
let object = CACHE.get(document.object().id().ok()?)?; let object = cache::OBJECTS.get(document.object().id().ok()?)?;
(object.id().str()?, object.in_reply_to().id().str()?) (object.id().str()?, object.in_reply_to().id().str()?)
}, },