From ecc840a89f32ab7e03f3f084e8b8cf92ef69299c Mon Sep 17 00:00:00 2001 From: "Willow (GHOST)" Date: Fri, 23 Oct 2026 16:27:59 +0100 Subject: [PATCH] feat(uplc): add quick internal pds validation checker status endpoint --- uplc/src/api.rs | 7 +++++ uplc/src/hosts.rs | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/uplc/src/api.rs b/uplc/src/api.rs index 962caff..5253685 100644 --- a/uplc/src/api.rs +++ b/uplc/src/api.rs @@ -36,6 +36,13 @@ pub async fn run_api(db: DB, stats: Arc>, cancel: CancellationToke let stats = stats.clone(); move || async move { Json(stats.read().await.json()) } }), + ) + .route( + "/v0/hosts/progress", + get({ + let db = db.clone(); + move || async move { Json(db.get_hosts_progress().expect("query hosts progress")) } + }), ); let host = env::var("HOST").unwrap_or(String::from("127.0.0.1")); diff --git a/uplc/src/hosts.rs b/uplc/src/hosts.rs index 767b9f2..d1b1e7b 100644 --- a/uplc/src/hosts.rs +++ b/uplc/src/hosts.rs @@ -245,6 +245,78 @@ pub struct HostStatus { pub attempts: i64, } +/// Summary of the PDS validity classifier's progress. +#[derive(serde::Serialize)] +pub struct HostsProgress { + pub total_hosts: u64, + pub checked_hosts: u64, + pub pending_hosts: u64, + pub valid_hosts: u64, + pub invalid_hosts: u64, + pub progress_pct: f64, + pub valid_hosts_list: Vec, + pub invalid_hosts_list: Vec, +} + +impl DB { + /// Return a summary of how far the PDS validity classifier has progressed. + /// the valid/invalid hosts lists isn't 100% accurate as it won't look at things + /// that aren't in the db because their auto classified by the is `is_clearly_invalid` + /// fn - and I cba to make this account for that + pub fn get_hosts_progress(&self) -> Result { + let db = self.handle()?; + let (total_hosts, checked_hosts, pending_hosts, valid_hosts, invalid_hosts) = db + .query_row( + r#" + SELECT + COUNT(*)::INT8 AS total_hosts, + COUNT(last_checked)::INT8 AS checked_hosts, + (COUNT(*) - COUNT(last_checked))::INT8 AS pending_hosts, + COUNT(*) FILTER (WHERE valid = true)::INT8 AS valid_hosts, + COUNT(*) FILTER (WHERE valid = false)::INT8 AS invalid_hosts + FROM hosts + "#, + [], + |row| { + Ok(( + row.get::<_, u64>(0)?, + row.get::<_, u64>(1)?, + row.get::<_, u64>(2)?, + row.get::<_, u64>(3)?, + row.get::<_, u64>(4)?, + )) + }, + )?; + + let valid_hosts_list: Vec = db + .prepare("SELECT host FROM hosts WHERE valid = true ORDER BY host")? + .query_map([], |row| row.get(0))? + .collect::, _>>()?; + + let invalid_hosts_list: Vec = db + .prepare("SELECT host FROM hosts WHERE valid = false ORDER BY host")? + .query_map([], |row| row.get(0))? + .collect::, _>>()?; + + let progress_pct = if total_hosts > 0 { + (checked_hosts as f64 / total_hosts as f64) * 100.0 + } else { + 0.0 + }; + + Ok(HostsProgress { + total_hosts, + checked_hosts, + pending_hosts, + valid_hosts, + invalid_hosts, + progress_pct, + valid_hosts_list, + invalid_hosts_list, + }) + } +} + #[cfg(test)] mod tests { use super::*; -- knotmirror 0.0.1