mirror of
https://git.alemi.dev/fedicharter.git
synced 2025-01-08 04:03:55 +01:00
feat: parse well-known, store parsed struct
This commit is contained in:
parent
322408e2dd
commit
806ff114ba
2 changed files with 31 additions and 17 deletions
|
@ -10,6 +10,7 @@ async-recursion = "1.0.5"
|
||||||
axum = "0.6.20"
|
axum = "0.6.20"
|
||||||
chrono = "0.4.31"
|
chrono = "0.4.31"
|
||||||
clap = { version = "4.4.6", features = ["derive"] }
|
clap = { version = "4.4.6", features = ["derive"] }
|
||||||
|
derive_more = "0.99.17"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
reqwest = { version = "0.11.20", features = ["json"] }
|
reqwest = { version = "0.11.20", features = ["json"] }
|
||||||
sea-orm = { version = "0.12.3", features = ["runtime-tokio-native-tls", "sqlx-sqlite", "sqlx-postgres"] }
|
sea-orm = { version = "0.12.3", features = ["runtime-tokio-native-tls", "sqlx-sqlite", "sqlx-postgres"] }
|
||||||
|
|
47
src/cache.rs
47
src/cache.rs
|
@ -1,8 +1,11 @@
|
||||||
use std::{sync::Arc, collections::HashMap, time::Duration};
|
use std::{sync::Arc, collections::HashMap};
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
use crate::nodeinfo::model::{NodeInfoOwned, Software, Services};
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use crate::nodeinfo::fetcher::node_info;
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
pub static ref CACHE : Arc<InstanceCache> = Arc::new(InstanceCache::default());
|
pub static ref CACHE : Arc<InstanceCache> = Arc::new(InstanceCache::default());
|
||||||
}
|
}
|
||||||
|
@ -11,33 +14,43 @@ const MAX_CACHE_AGE : i64 = 86400;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct InstanceCache {
|
pub struct InstanceCache {
|
||||||
store: RwLock<HashMap<String, (i64, Option<serde_json::Value>)>>,
|
store: RwLock<HashMap<String, (i64, NodeInfoOwned)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstanceCache {
|
impl InstanceCache {
|
||||||
pub async fn instance_metadata(&self, domain: &str) -> reqwest::Result<Option<serde_json::Value>> {
|
pub async fn instance_metadata(&self, domain: &str) -> reqwest::Result<NodeInfoOwned> {
|
||||||
let now = Utc::now().timestamp();
|
let now = Utc::now().timestamp();
|
||||||
|
|
||||||
if let Some((age, value)) = self.store.read().await.get(domain) {
|
if let Some((age, value)) = self.store.read().await.get(domain) {
|
||||||
if now - age < MAX_CACHE_AGE {
|
if now - age < MAX_CACHE_AGE {
|
||||||
return Ok(value.clone());
|
return Ok(clone_node_info(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = reqwest::Client::builder()
|
let info = node_info(domain).await?;
|
||||||
.timeout(Duration::from_secs(5))
|
|
||||||
.build()?
|
|
||||||
.get(format!("https://{}/nodeinfo/2.0.json", domain))
|
|
||||||
.send()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let value = response
|
self.store.write().await.insert(domain.to_string(), (now, clone_node_info(&info)));
|
||||||
.json::<serde_json::Value>()
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
self.store.write().await.insert(domain.to_string(), (now, value.clone()));
|
Ok(info)
|
||||||
|
}
|
||||||
Ok(value)
|
}
|
||||||
|
|
||||||
|
fn clone_node_info(node: &NodeInfoOwned) -> NodeInfoOwned {
|
||||||
|
NodeInfoOwned {
|
||||||
|
version: node.version.clone(),
|
||||||
|
software: Software {
|
||||||
|
name: node.software.name.clone(),
|
||||||
|
version: node.software.version.clone(),
|
||||||
|
repository: node.software.repository.clone(),
|
||||||
|
homepage: node.software.homepage.clone(),
|
||||||
|
},
|
||||||
|
protocols: node.protocols.clone(),
|
||||||
|
services: Services {
|
||||||
|
inbound: node.services.inbound.clone(),
|
||||||
|
outbound: node.services.outbound.clone(),
|
||||||
|
},
|
||||||
|
open_registrations: node.open_registrations,
|
||||||
|
usage: node.usage.clone(),
|
||||||
|
metadata: node.metadata.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue