fix(web): properly fetch attributed_to/quote_url

also use cache::resolve so we centralize fetching a bit
This commit is contained in:
əlemi 2024-12-28 20:18:01 +01:00
parent b1830e68f4
commit c56e69aa20
Signed by: alemi
GPG key ID: A4895B84D311642C
4 changed files with 21 additions and 30 deletions

View file

@ -17,9 +17,6 @@ pub fn ActorHeader() -> impl IntoView {
Some(x) => Some(x.clone()), Some(x) => Some(x.clone()),
None => { None => {
let user = cache::OBJECTS.resolve(&id, U::Actor, auth).await?; let user = cache::OBJECTS.resolve(&id, U::Actor, auth).await?;
if let Ok(url) = user.url().id() {
cache::WEBFINGER.store(&url, user.id().unwrap_or_default().to_string());
}
Some(user) Some(user)
}, },
} }

View file

@ -108,6 +108,11 @@ impl DashmapCache<Object> {
}, },
}; };
cache::OBJECTS.store(&full_key, obj.clone()); cache::OBJECTS.store(&full_key, obj.clone());
if matches!(kind, UriClass::Actor) {
if let Ok(url) = apb::Object::url(&*obj).id() { // TODO name clashes
cache::WEBFINGER.store(&url, full_key);
}
}
Some(obj) Some(obj)
}, },
} }

View file

@ -19,9 +19,15 @@ pub fn ObjectView() -> impl IntoView {
move |(oid, _loading)| async move { move |(oid, _loading)| async move {
tracing::info!("rerunning fetcher"); tracing::info!("rerunning fetcher");
let obj = cache::OBJECTS.resolve(&oid, U::Object, auth).await?; let obj = cache::OBJECTS.resolve(&oid, U::Object, auth).await?;
// TODO these two can be parallelized
if let Ok(author) = obj.attributed_to().id() { if let Ok(author) = obj.attributed_to().id() {
cache::OBJECTS.resolve(&author, U::Actor, auth).await; cache::OBJECTS.resolve(&author, U::Actor, auth).await;
} }
if let Ok(quote) = obj.quote_url().id() {
cache::OBJECTS.resolve(&quote, U::Object, auth).await;
}
Some(obj) Some(obj)
// if let Ok(ctx) = obj.context().id() { // if let Ok(ctx) = obj.context().id() {

View file

@ -169,20 +169,20 @@ pub async fn process_activities(activities: Vec<serde_json::Value>, auth: Auth)
if let Ok(uid) = activity.attributed_to().id() { if let Ok(uid) = activity.attributed_to().id() {
if cache::OBJECTS.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(deep_fetch_and_update(U::Actor, uid, auth)));
} }
} }
if let Ok(uid) = activity.actor().id() { if let Ok(uid) = activity.actor().id() {
if cache::OBJECTS.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(deep_fetch_and_update(U::Actor, uid, auth)));
} }
} }
} }
for user in actors_seen { for user in actors_seen {
sub_tasks.push(Box::pin(fetch_and_update(U::Actor, user, auth))); sub_tasks.push(Box::pin(deep_fetch_and_update(U::Actor, user, auth)));
} }
futures::future::join_all(sub_tasks).await; futures::future::join_all(sub_tasks).await;
@ -190,33 +190,16 @@ pub async fn process_activities(activities: Vec<serde_json::Value>, auth: Auth)
out out
} }
async fn fetch_and_update(kind: U, id: String, auth: Auth) {
match Http::fetch::<serde_json::Value>(&Uri::api(kind, &id, false), auth).await {
Err(e) => console_warn(&format!("could not fetch '{id}': {e}")),
Ok(data) => {
if data.actor_type().is_ok() {
if let Ok(url) = data.url().id() {
cache::WEBFINGER.store(&id, url);
}
}
cache::OBJECTS.store(&id, Arc::new(data));
},
}
}
async fn deep_fetch_and_update(kind: U, id: String, auth: Auth) { async fn deep_fetch_and_update(kind: U, id: String, auth: Auth) {
fetch_and_update(kind, id.clone(), auth).await; if let Some(obj) = cache::OBJECTS.resolve(&id, kind, auth).await {
if let Some(obj) = cache::OBJECTS.get(&id) {
if let Ok(quote) = obj.quote_url().id() { if let Ok(quote) = obj.quote_url().id() {
fetch_and_update(U::Object, quote, auth).await; cache::OBJECTS.resolve(&quote, U::Object, auth).await;
} }
if let Some(actor_id) = match kind { if let Ok(actor) = obj.actor().id() {
U::Object => obj.attributed_to().id().ok(), cache::OBJECTS.resolve(&actor, U::Actor, auth).await;
U::Activity => obj.actor().id().ok(), }
U::Actor => None, if let Ok(attributed_to) = obj.attributed_to().id() {
U::Hashtag => None, cache::OBJECTS.resolve(&attributed_to, U::Actor, auth).await;
} {
fetch_and_update(U::Actor, actor_id, auth).await;
} }
} }
} }