feat: parse well-known, store parsed struct

This commit is contained in:
əlemi 2023-10-18 00:37:08 +02:00
parent 322408e2dd
commit 806ff114ba
Signed by: alemi
GPG key ID: A4895B84D311642C
2 changed files with 31 additions and 17 deletions

View file

@ -10,6 +10,7 @@ async-recursion = "1.0.5"
axum = "0.6.20"
chrono = "0.4.31"
clap = { version = "4.4.6", features = ["derive"] }
derive_more = "0.99.17"
lazy_static = "1.4.0"
reqwest = { version = "0.11.20", features = ["json"] }
sea-orm = { version = "0.12.3", features = ["runtime-tokio-native-tls", "sqlx-sqlite", "sqlx-postgres"] }

View file

@ -1,8 +1,11 @@
use std::{sync::Arc, collections::HashMap, time::Duration};
use std::{sync::Arc, collections::HashMap};
use chrono::Utc;
use crate::nodeinfo::model::{NodeInfoOwned, Software, Services};
use tokio::sync::RwLock;
use crate::nodeinfo::fetcher::node_info;
lazy_static::lazy_static! {
pub static ref CACHE : Arc<InstanceCache> = Arc::new(InstanceCache::default());
}
@ -11,33 +14,43 @@ const MAX_CACHE_AGE : i64 = 86400;
#[derive(Default)]
pub struct InstanceCache {
store: RwLock<HashMap<String, (i64, Option<serde_json::Value>)>>,
store: RwLock<HashMap<String, (i64, NodeInfoOwned)>>,
}
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();
if let Some((age, value)) = self.store.read().await.get(domain) {
if now - age < MAX_CACHE_AGE {
return Ok(value.clone());
return Ok(clone_node_info(value));
}
}
let response = reqwest::Client::builder()
.timeout(Duration::from_secs(5))
.build()?
.get(format!("https://{}/nodeinfo/2.0.json", domain))
.send()
.await?;
let info = node_info(domain).await?;
let value = response
.json::<serde_json::Value>()
.await
.ok();
self.store.write().await.insert(domain.to_string(), (now, clone_node_info(&info)));
self.store.write().await.insert(domain.to_string(), (now, value.clone()));
Ok(value)
Ok(info)
}
}
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(),
}
}